MediaWiki extension: IncludeSpecialPage

InfoDabble > Tech Notes > MediaWiki > MediaWiki extension: IncludeSpecialPage
Jump to: navigation, search
This is a MediaWiki Extension
IncludeSpecialPage

Release status: beta

Type: Parser extension
Description: Inserts the output of a special page into a normal page.
Author: Eric Hartwell
Version: 0.5 (28 August 2007)
MediaWiki: Tested on 1.10
Download: Code (this article)

Contents

[edit] What can this extension do?

This project is still under development.

This extension inserts the output of a special page into a normal page. It was designed to work with Special:Version and Special:Statistics, but it should work with any display-only special page.

[edit] Usage

The only parameter is the name of the special page. For example, to include Special:Version, type

{{:includespecialpage:Version}}

Normal user restrictions apply - this extension is run with the user's permissions.

[edit] Installation

Copy IncludeSpecialPage.php to the extensions directory, then update LocalSettings.php.

[edit] Parameters

[edit] Changes to LocalSettings.php

require_once("$IP/extensions/IncludeSpecialPage/IncludeSpecialPage.php");

[edit] Code

<?php
/**
 * IncludeSpecialPage.php
 * This Extension does .......
 * written by Eric Hartwell  http://www.ehartwell.com/about
 * To activate the functionality of this extension include the following in your
 * LocalSettings.php file:
 * require_once('$IP/extensions/IncludeSpecialPage/IncludeSpecialPage.php');
 */
 
### require_once('$IP/includes/SpecialPage.php');
 
if(! defined( 'MEDIAWIKI' ) ) {
   echo( "This is an extension to the MediaWiki package and cannot be run standalone.\n" );
   die( -1 );
}
 
// Replace validextensionclass with: specialpage, parserhook, variable (multiple functionality), other
$wgExtensionCredits['parserhook'][] = array(
     'name' => 'IncludeSpecialPage',
     'author' =>'Eric Hartwell', 
     'url' => 'http://www.ehartwell.com',
     'description' => 'Inserts the output of a special page into a normal page.',
    );
 
# Define a setup function
$wgExtensionFunctions[] = 'wfIncludeSpecialPage_Setup';
# Add a hook to initialise the magic word
$wgHooks['LanguageGetMagic'][]       = 'wfIncludeSpecialPage_Magic';
 
function wfIncludeSpecialPage_Setup() {
        global $wgParser;
        # Set a function hook associating the "includespecialpage" magic word with our function
        $wgParser->setFunctionHook( 'includespecialpage', 'wfIncludeSpecialPage_Render' );
}
 
function wfIncludeSpecialPage_Magic( &$magicWords, $langCode ) {
        # Add the magic word
        # The first array element is case sensitive, in this case it is not case sensitive
        # All remaining elements are synonyms for our parser function
        $magicWords['includespecialpage'] = array( 0, 'includespecialpage');
        # unless we return true, other parser functions extensions won't get loaded.
        return true;
}
 
# The parser function itself
# The input parameters are wikitext with templates expanded
# The output should be wikitext too
function wfIncludeSpecialPage_Render( &$parser, $param1 = '', $param2 = '' ) {
 
		// SpecialPage::capturePath() is is supposed to work, but it doesn't 
		// preserve the parser state. Also I can't get it to work at all.
		// capturePath is just like executePath() except it returns the HTML instead of outputting it.
	 	// Returns false if there was no such special page, or a title object if it was a redirect.
		// $html = SpecialPage::capturePath( new Title('Special:' . $param1) );
 
		// Use a new output stream so we don't munge the active one
		global $wgOut, $wgParser;			// Output stream and parser
		$oldOut = $wgOut;
		$wgOut = new OutputPage;
###		$oldParser = clone $wgParser;		// Use a clone of the parser
var_dump($wgParser->mUniqPrefix);
##  $oldParser = serialize($wgParser);
		$oldParser = $wgParser;				// Save the parser
		$wgParser = new Parser();			// .. and use a new one
 
		// Run the special function		        
        $special = new SpecialPage( $param1 );
        $special->execute( $param2 );
		$html = $wgOut->getHTML();			// Extract generated text
 
		// Restore state (well, parser at least, mostly, usually)
##$wgParser = unserialize($oldParser);
var_dump($wgParser->mUniqPrefix);
		$wgParser = $oldParser;				// Restore the parser state
		$wgOut 	  = $oldOut;				// Restore the original output
 
		// return unparsed HTML output instead of wikitext output
		return array($html, 'noparse' => true, 'isHTML' => true);
}
 
?>

[edit] Implementation

[edit] Troubleshooting

Things to remember:

  1. The MediaWiki parser is not reentrant.
  2. The MediaWiki parser is not reentrant.
  3. The MediaWiki parser is not reentrant.

While the basic code seems to work just fine, as soon as you add other extension tags the output starts showing markers like this:

UNIQ52dd307973681df6-source-00000002-QINU

This is the format the parser uses for interim processing of inline tags. Clearly something is getting confused. What to do?

  • Doesn't work: $oldParser = clone $wgParser; // Use a clone of the parser and restore it later.
    • When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables, will remain references. If a __clone() method is defined, then the newly created object's __clone() method will be called, to allow any necessary properties that need to be changed -- Object cloning - PHP Manual
  • Doesn't work: $oldParser = serialize($wgParser); // Serialize the parser and restore it later
  • Works better: $oldParser = $wgParser; $wgParser = new Parser(); // Create a new parser and restore the old one later

[edit] Tips, Tricks, Hoops

[edit] See also