Extension:C Style Wiki Includes

From MediaWiki.org

Jump to: navigation, search

           

Manual on MediaWiki Extensions
List of MediaWiki Extensions
Crystal Clear action run.png
C Style Wiki Includes

Release status: beta

Implementation  Extended syntax
Description Allows including HTML, WikiText, or PlainText using an #include tag.
Author(s)  Daniel Friesen (DantmanTalk)
Last Version  unknown
MediaWiki  1.8.x, 1.9x
License No license specified
Download Wiki-Tools.com or this page

check usage (experimental)

Contents

[edit] Rationale and Features

I saw one user on my wiki add an amusing line on their user page instead of a #REDIRECT to another userpage... They basically used a C Style include with an interwiki link to their normal Userpage.

That gave me the idea to setup real C style includes. HTML, WikiText, and then decided to add Text.

I'll have to thank the ProtectSection extension, because I used their extension as a base to know what functions to use and how to make adding unsafe ones fail when not added by a privileged user.

[edit] Usage and Installation

Full information on the C Style Wiki Includes extension can be found at Wiki-Tools.com.

[edit] Code

The site's being taken down and every thing's being done from scratch... So here's the code... Dantman

<?php
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# http://www.gnu.org/copyleft/gpl.html
 
/**
 * @author Daniel Friesen <dan_the_man@telus.net>
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
 */
 
if( !defined( 'MEDIAWIKI' ) ) die( "This is an extension to the MediaWiki package and cannot be run standalone." );
 
// Two new permissions
$wgAvailableRights[] = 'cwikiinclude';
 
$wgExtensionFunctions[] = 'efCWikiIncludeSetup';
 
// Register hooks
$wgHooks['ParserAfterTidy'][] = 'efCWikiAfterParse';
$wgHooks['EditFilter'][] = 'efCheckCWikiInclude';
$wgHooks['ParserBeforeStrip'][] = 'efCWikiBeforeParse';
 
$wgExtensionCredits['parserhook'][] = array(
	'name' => 'C Style Wiki Includes',
	'url' => 'http://www.mediawiki.org/wiki/Extension:C_Style_Wiki_Includes',
	'author' => '[http://central.wiki-tools.com/wiki/User:Dantman Daniel Friesen]',
	'description' => 'C Style WikiText and HTML includes.',
);
 
$egCWikiInclude_limit = 3;
$egCWikiWikiText_html = "/^#include\s*\"(https?:\/\/[^<>\"']*?)\"(;?)$/sim";
$egCWikiWikiText_text = "/^#include\s*{(https?:\/\/[^<>\"']*?)}(;?)$/sim";
$egCWikiWikiText_wiki = "/^#include\s*<(https?:\/\/[^<>\"']*?)>(;?)$/sim";
$egCWikiInclude_html = "/<tt>#include\s*&quot;(https?:\/\/[^<>\"']*?)&quot;(;?)<\/tt><br \/>/sim";
$egCWikiInclude_text = "/<tt>#include\s*{(https?:\/\/[^<>\"']*?)}(;?)<\/tt>/sim";
$egCWikiInclude_wiki = "/<tt><nowiki>#include\s*<(https?:\/\/[^<>\"']*?)>(;?)<\/nowiki><\/tt><br \/>/sim";
function efCWikiIncludeSetup() {
	global $wgMessageCache;
	$wgMessageCache->addMessages(
		array(
			'cwikiinclude_add_html' => 
				'You tried to add a C Style HTML Include',
			'cwikiinclude_modify_html' => 
				'You tried to modify a C Style HTML Include',
			'cwikiinclude_forbidden' =>
				'Forbidden',
		)
	);
}
 
 
function efCWikiBeforeParse( &$parser, &$text, &$stripState ) {
	global $egCWikiWikiText_html, $egCWikiWikiText_text, $egCWikiWikiText_wiki, $egCWikiInclude_wiki, $egCWikiInclude_limit;
 
	/* Escape The Includes */
	$text = preg_replace( array(
		$egCWikiWikiText_html,
		$egCWikiWikiText_text,
		$egCWikiWikiText_wiki
	), array(
		"<tt><nowiki>#include \"\\1\"\\2</nowiki></tt><br />",
		"<tt><nowiki>#include {\\1}\\2</nowiki></tt><br />",
		"<tt><nowiki>#include <\\1>\\2</nowiki></tt><br />"
	), $text );
 
	/* Do the WikiText include */
	$text = preg_replace( $egCWikiInclude_wiki.'e', 'efCWikiIncludeCallback( "\\0", false, "\\1" )', $text, $egCWikiInclude_limit );
 
	return true;
}
function efCWikiAfterParse( &$parser, &$text ) { 
	global $egCWikiInclude_limit, $egCWikiInclude_html, $egCWikiInclude_text;
 
	/* Do the HTML include */
	$text = preg_replace( array(
		$egCWikiInclude_html.'e',
		$egCWikiInclude_text.'e'
	), array(
		'efCWikiIncludeCallback( "\\0", false, html_entity_decode( "\\1" , ENT_QUOTES ) )',
		'efCWikiIncludeCallback( "\\0", true, html_entity_decode( "\\1" , ENT_QUOTES ) )'
	), $text, $egCWikiInclude_limit );
 
	return true;
}
 
function efCWikiIncludeCallback( $original, $escapeHTML, $url ) {
	global $wgMemc, $wgUser, $wgOut, $wgTitle;
 
	$key = wfMemcKey( 'include', $url );
	$content = $wgMemc->get( $key );
	if( $content == "" ) {
		$content = Http::get( $url );
		if( $content ) {
			$wgMemc->set( $key, $content, time() + 86400 );
		}
	}
	if( $escapeHTML ) {
		$text = htmlspecialchars( $text );
	}
	if( $content === false ) {
		$content = $original;
	}
	return $content;
}
 
function efCWikiDeleteCallback( $url ) {
	global $wgMemc;
	$key = wfMemcKey( 'include', $url );
	$wgMemc->delete( $key );
	return "";
}
 
/**
 * @todo Document
 * @param $editpage
 * @param $textbox1
 * @param $section
 */
function efCheckCWikiInclude( $editpage, $textbox1, $section )  {
	global $egCWikiInclude_limit, $egCWikiWikiText_html, $egCWikiWikiText_text, $egCWikiWikiText_wiki;
	# check for partial protection 
	global $wgUser,$wgParser;
 
	# Purge memcached for a URL when attempting a save
	preg_replace( array(
		$egCWikiWikiText_html.'e',
		$egCWikiWikiText_text.'e',
		$egCWikiWikiText_wiki.'e'
	), array_fill ( 0, 3,
		'efCWikiDeleteCallback( html_entity_decode( "\\1" , ENT_QUOTES ) )'
	), $text, $egCWikiInclude_limit );
 
	if ( !$wgUser->isAllowed( 'cwikiinclude_html' ) ) {
		$modifyProtect = false; 
		$text1 = $editpage->mArticle->getContent(true);
 
		if( $section != '' ) {
			if( $section == 'new' ) {
				$text1 = "";
			} else {
				$text1 = $wgParser->getSection( $text1, $section );
			}
		}
 
		$text2 = $textbox1;
 
		preg_match_all( $egCWikiWikiText_html, $text1, $list1, PREG_SET_ORDER );
		preg_match_all( $egCWikiWikiText_html, $text2, $list2, PREG_SET_ORDER );
 
		if( count($list1) < count($list2)) { 
			$msg = wfMsg( 'cwikiinclude_add_html'); 
			$modifyProtect = true; 
		}
		else for ( $i=0 ; $i < count( $list1 ); $i++ ) {
			if( $list1[$i][0] != $list2[$i][0]) { 
				$msg = wfMsg( 'cwikiinclude_modify_html' );
				$modifyProtect = true; 
				break;
			}
		}
 
		if( $modifyProtect ) {
			global $wgOut;
			$wgOut->setPageTitle( wfMsg( 'cwikiinclude_forbidden' ) );
			$wgOut->addWikiText($msg);
			return false;
		}
	}
	return true;
}

[edit] See also