How to Add a Custom Function to MediaWiki

Recently, I wanted to add some dynamic content to a Mediawiki page : I wanted a project page to show how many lines of code the project currently had, and therefore I wanted something like <linecount> to be converted into something special.

Piece of cake ? Piece of cake. Adding custom tags or custom complex functions to your wiki is really easy, and here is how it can be done.

Adding a custom tag

For example, let's create the HTML tag <ozh>. Declaring a custom HTML tags in Mediawiki is done in 3 steps :

  1. Register a new function :
    $wgExtensionFunctions[] = 'registerSampleTag';
    $wgExtensionCredits['parserhook'][] = array(
    	'name' => 'SampleTag',
    	'author' => 'Ozh',
    	'url' => 'http://planetozh.com/',
    );
  2. Tell the wiki that this function will be triggered by tag <ozh>
    function registerSampleTag() {
        global $wgParser;
        $wgParser->setHook('ozh', 'printSampleTag');
    }
  3. Define your special function that will take care of text enclosed in your new tag
    function printSampleTag($input,$params) {
    	foreach ($params as $key=>$value) {
    		$args .= "<li>$key = *$value*</li>\n";
    	}
    	return('Text : '.$input.'<br/>Arguments :<ul>'.$args.'</ul>');
    }

Put these 3 functions in a file named for example sampleExtension.php in directory mediawiki/extensions, then edit mediawiki/LocalSettings.php and add the following at the end of the file, before the closing PHP tag ?> :

include("extensions/sampleExtension.php");

That's it. Now, whenever your write something like

<ozh stuff=1 thing="someparam">some text</ozh>

it will output

Text : some text
Arguments :
	stuff = 1
	thing = someparam

Ok, not the most useful stuff, but you get the idea :)

Adding a custom complex function

Now, you want to create something more complex, for example you'd like a custom function adequately named ozh that would convert "{{ozh:34|Quake|PHP}}" converted into "is 34 years old, plays Quake and writes poor PHP".

Your custom function declaration goes through 3 similar steps :

// Step 1 : add a new function to register
$wgExtensionFunctions[] = 'registerSampleFunction';
$wgExtensionCredits['parserhook'][] = array(
	'name' => 'SampleFunction',
	'author' => 'Ozh',
	'url' => 'http://planetozh.com/',
);

// Step 2 : tell the Wiki that this function will be
// triggered by function tag {{ozh}}
function registerSampleFunction() {
    global $wgParser;
    $wgParser->setFunctionHook('ozh', 'printSampleFunction');
}

// Step 3 : now define our function
function printSampleFunction(&$parser, $arg1, $arg2, $arg3) {
	return("is $arg1 years old, plays $arg2 and writes poor $arg3");
}

So …

How simple was it ?

For the curious readers, adding a line count from a subversion project was done with a bash script like :

svn export --username joe --password 123456 --force http://svn.project.com/ /home/ozh/project
find /home/ozh/project -name '*.*' | xargs wc -l | grep total | sed -e 's/ total//' > /home/ozh/project/line.count

The script is run periodically via cron, and a custom tag <linecount> simply calls a function that returns file_get_content('/home/ozh/project/line.count');

3 comments

  1. Vinu

    If I want to add a RSS feed to each page of the wiki how do I do that?? Are there any plugins available?

  2. m2

    This is how you can add an rss feed to your special pages:

    Find the corresponding Special page i.e. include/SpecialWantedpages.php

    Open this file and at the bottom where: function wfSpecial… is located, add on the next line: global $wgRequest;

    At the end of the function add just above the doQuery:
    if ( ! $pp->doFeed( $wgRequest->getVal( 'feed' ), $limit ) )

  3. Christian Boltz

    I just spent an hour to find out how I can use wiki tags in $input. Therefore I'm adding it here to avoid that another user has to waste another hour ;-)

    My method probably works with Mediawiki >= 1.8, I tested with 1.10.

    Instead of

    function printSampleTag($input,$params)

    use

    function printSampleTag($input,$params,$parser)

    and then call

    $ret = $parser->recursiveTagParse($input);

    $ret will then contain HTML code with wiki tags expanded, clickable links etc. – just as every other wiki page.

Comments are closed.