Extending MediaWiki

MediaWiki is the software that drives Wikipedia, a huge online collaborative encyclopedia that is at times at the heart of a fair amount of controvery having to do with matters of the site’s reliability, given that it’s authored by Joe Public. When I’ve installed wikis before, I’ve usually gone with phpwiki, which is very simple and somewhat less intimidating than Mediawiki. My new company decided to use a wiki as the starting point for our intranet, and I decided to take the plunge and try out MediaWiki.

As it turns out, the software’s a breeze to install and a dream to use. Its interface is crisp and simple to navigate, and it’s got loads of formatting options. Among the things we wanted to add to the wiki to make it more extranet-like was our company del.icio.us feed, which contains links relevant to our plans. Naturally, rather than just showing the raw RSS feed, we wanted to parse the feed and display it as a list of links. Which presented a bit of a problem, as MediaWiki out of the box doesn’t allow parsing of code. So I couldn’t very well just put in a PHP block that’d parse the feed and convert it to a list of links.

I read around a little and confirmed my suspicion that you can write extensions for MediaWiki. It’s actually very simple. Because MediaWiki’s schtick is to parse tags, the extensions API assumes that you’re going to define a new tag to be parsed, and once you register the extension, any time you use the newly defined html-style tag in an entry, it passes the content between the tags to the extension and prints the return value to the screen in place of the tag and its contents. So for example, you could define a tag “<name>” and have its extension just return your name. Whenever the wiki’s parsing a page and runs across the <name> tag, it’ll substitute your name. In my case, I needed a tag that’d parse a PHP block. The extension I wrote is as follows:

//Add the hook function call to an array defined earlier in the wiki code execution.
$wgExtensionFunctions[] = “wfPhpParse”;

//This is the hook function. It adds the tag to the wiki parser and tells it what callback function to use.
function wfPhpParse() {
global $wgParser;
# register the extension with the WikiText parser
$wgParser->setHook( “phpcode”, “renderPhpParse” );
}

# The callback function for converting the input text to HTML output
function renderPhpParse( $input ) {
//Eval the code between the tags.
return eval($input);
}

Once you’ve written the extension, you add a line to LocalSettings.php in the root that includes the extension file. And that’s it. To use the extension within a wiki entry, I’d type something like the following:

<phpcode>
$txt="The date is " . date('M d, Y') . ".";
return $txt;
</phpcode>

Note that I’m building my text and returning the value. This is because a PHP eval (used in my extension) will execute the code in line unless it finds a return at the end. So if you want the eval to return its value to the extension function to be returned to the main wiki code rather than just executing in line (which will give you weird results), you need to add any output to a variable and return the variable. This extension probably wouldn’t be the best in the world to use for a public wiki because it will indiscriminately execute PHP code submitted by users, and a malicious user could, for example, add to the main page an infinite loop that’d bring your site crashing to its knees. In my case, the wiki I’m administering is for private corporate use, and all users are trusted, so I feel ok about letting them add PHP code if necessary. I provide the example merely to demonstrate how absurdly easy it is to extend an already very cool piece of software.

13 thoughts on “Extending MediaWiki

  1. MK says:

    I have the same question as Sam. How can I make it appear inside the box? My idea is to display a predefined dynamic DHTML menu on certain content pages using HTML_TreeMenuXL. Can’t get it to work…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s