How to become a MediaWiki hacker/Extension Writing Tutorial

From mediawiki.org
TODO: Developers should start from Extension:BoilerPlate or the cookiecutter-mediawiki-extension, not Extension:Examples; also promote MediaWiki-Vagrant as well as checking out MediaWiki core

These notes are a reference to help you get started writing a MediaWiki extension that takes advantage of MediaWiki's SpecialPage functionality.

Target audience: people unfamiliar with hacking MediaWiki, and particularly those interested in building extensions.

Goal of tutorial: have a basic grasp of a MediaWiki extension and know how to push changes upstream for review and potential integration with the MediaWiki ecosystem

More extensive documentation for developing extensions can be found in the manual under Developing extensions.

Overview[edit]

In this workshop, we will go over the basic coding toolchain, particularly for MediaWiki extensions. We will cover some of the topics in How to become a MediaWiki hacker.

We will go over the anatomy of an extension, some of the things you can do with an extension, basic localization, basic SpecialPage functionality and what you can do with it, and how to get your code changes pushed upstream. We will follow some basic examples and be guided through much of the process.

Setup[edit]

This tutorial expects that you are working on a system already running MediaWiki checked out from our Git repository (Download from Git).

  1. Check-out a copy of the 'Examples' extension into your MediaWiki installation's 'extensions' folder:
    git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/examples.git
    
  2. Add the proper installation line to your LocalSettings.php file:
    wfLoadExtension( 'examples' );
    

Exercises[edit]

Exercise 1: Hello world[edit]

  1. Visit the Examples special page to make sure it works properly (the URL will be something like http://localhost/your_wiki/Special:HelloWorld). You should see a tab marked “Special page” with the text “This is an example!” on it.
  2. Add to the execute function in extensions/examples/includes/SpecialHelloWorld.php the following line:
    echo 'hello world!';
    
    echo is a PHP command that prints out text and the content of variables.
  3. Visit the Examples special page to make sure you see 'hello world!' printed out on the screen.

Exercise 2: Introduction to i18n files[edit]

Internationalisation ("i18n") files are how we handle message translation in MediaWiki. Messages should be added in English only; translations will be added automatically by the translation community. All messages that get displayed to the user should come from messages in the i18n files rather than hard-coded text.

  1. Create a new English message in examples/i18n/en.json that says "hello world". Eg:
    "examples-hello_world": "hello world!",
    
  2. Make sure you set the decimal correctly in case the code had been added to the of the list in the file. The code in the file is self-explanatory in this regard.
  3. Remove the 'echo' line from SpecialHelloWorld.php.
  4. Make the execute function in SpecialHelloWorld.php use your new message. Eg:
        $out = $this->getOutput();
        $out->addWikimsg( 'examples-hello_world' );
    
  5. Visit the Examples special page to make sure it works properly. You should see "hello world!" printed out to the screen.

Exercise 3: Dynamic i18n messages[edit]

While you always want to make sure that user-facing messages come from the i18n files, sometimes you want the content of your message to be variable. For instance, maybe you want to say 'hello <your name here>'. This is easy to do with i18n parameters. Parameters are indicated in i18n messages with $1, $2, etc., which are then mapped to the parameters you pass into the function to call the message.

  1. Change the 'hello world' message you created in i18n/en.json to use $1 instead of the word 'world':
    "examples-hello_world" : "hello $1!",
    
  2. Add a 'qqq' (documentation) message in i18n/qqq.json for the 'examples-hello_world' message explaining how the message will be used and what the parameter is for. This helps give context to the translators while they are making their translations.
  3. Create a method in SpecialHelloWorld.php that will return a random name. You could create an array of a few possible names and use array_rand() function.
    	public function getRandomName() {
            	$ar = ['John', 'Mary', 'James', 'William'];
    		return $ar[array_rand($ar)];
    	}
    
  4. Add the returned random name as the second parameter to the addWikimsg call in the execute method:
    $out->addWikimsg( 'examples-hello_world', $this->getRandomName() );
    
  5. Visit the Examples special page to make sure it works properly. Refresh a few times to see if it's properly returning 'hello <random name>!'

Exercise 4: Introducing $wgRequest[edit]

MediaWiki makes it easy to retrieve $_GET, $_POST, and $_COOKIE values with the global variable $wgRequest. We will use it to retrieve a $_GET value, so that we can specify a desired name to greet simply by passing it in the URL.

  1. Make sure that the $wgRequest is available to you inside the execute() method in SpecialHelloWorld.php:
    global $wgRequest;
    
  2. Use the $wgRequest->getText() method to retrieve the value of the $_GET parameter 'name'. The first parameter of $wgRequest->getText() is the string of the parameter name to retrieve.
    $out->addWikimsg( 'examples-hello_world', $wgRequest->getText( 'name' ) );
    
  3. The second parameter is the default value to return if there has been no value supplied for the requested parameter. For fun, let's make the default value be a random name from our random name generator:
    $out->addWikimsg( 'examples-hello_world', $wgRequest->getText( 'name', $this->getRandomName() ) );
    
  4. Visit the Examples special page, but this time add ?name=Harshad to the URL. You should now see 'Hello Harshad!' on your screen. do it like this: http://localhost/wiki/index.php?title=Special%3AHelloWorld&name=Harshad.
  5. Now, remove the query string from the URL and load the page. Your SpecialPage should now be greeting one of the random names you chose!

Submitting your changes[edit]

Now that you've successfully made some changes to the examples MediaWiki extension, you want to submit them in to the MediaWiki code review tool Gerrit for review, eventual merging back into the main code branch, and then deployment.

See How to submit a patch in "Gerrit/Tutorial." If you follow the steps there, be clear in your bug report and commit message that your change is a test unless of course it is a genuine improvement to the Examples extension.

Further Resources[edit]

REQUIRED READING[edit]

This reading is an absolute must for anyone making contributions to MediaWiki

Handy guides and documentation[edit]