How to become a MediaWiki hacker/Extension Writing Tutorial

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

Overview
In this workshop, we will go over the basic coding toolchain, particularly for MediaWiki extensions, and our code intake/review/merge/deploy/release workflow. We will cover some of the topics in "HOWTO 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 the much of the process.

Setup
This tutorial expects that you are working on a system already running MediaWiki checked out from our Subversion repository, and that you have a Subversion client already installed.


 * 1) Check-out a copy of the 'Example' extension into your MediaWiki installation's 'extensions' folder: svn checkout http://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions/examples/
 * 2) Add the proper installation line to your LocalSettings.php file: require_once( "$IP/extensions/Example/Example.php" );

Exercise 1: Hello world

 * 1) Visit the Example special page to make sure it works properly (the URL will be something like http://localhost/your_wiki/Special:Example)
 * 2) Modify the 'execute' method in Example.body.php to print out 'hello world!': echo 'hello world!';
 * 3) Visit the Example special page to make sure you see 'hello world!' printed out on the screen

Exercise 2: Introduction to i18n files
Internationalisation ("i18n") files are how we handle message translation in MediaWiki. Messages should be added in English only; translations will be added automagically 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 Example.i18n.php that says 'hello world'. Eg: 'example-hello_world' => 'hello world!',
 * 2) Remove the 'echo' line from Example.body.php
 * 3) Make the execute method in Example.body.php use your new message. Eg: $wgOut->addWikimsg( 'example-hello_world' );
 * 4) Visit the Example special page to make sure it works properly. You should see 'hello world!' printed out to the screen.

Exercise 3: Dynamic i18n messages
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 '. 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 Example.i18n.php to use '$1' instead of the word 'world': 'example-hello_world' => 'hello $1!',
 * 2) Add a 'qqq' (documentation) message for the 'example-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 Example.body.php that will return a random name. You could create an array of a few possible names and use array_rand
 * 4) Add the returned random name as the second parameter to the 'addWikimsg' call in the execute method: $wgOut->addWikimsg( 'example-hello_world', $this->getRandomName );
 * 5) Visit the Example special page to make sure it works properly. Refresh a few times to see if it's properly returning 'Hello !'

Exercise 4: Introducing $wgRequest
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 Example.body.php: global $wgRequest;
 * 2) Use the $wgRequest->getText method to retrive the value of the $_GET parameter 'name'. The first parameter of $wgRequest->getText is the string of the parameter name to retrieve. $wgOut->addWikimsg( 'example-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: $wgOut->addWikimsg( 'example-hello_world', $wgRequest->getText( 'name', $this->getRandomName ));
 * 4) Visit the Example special page, but this time add '?name=Harshad' to the URL. You should now see 'Hellow Harshad!' on your screen.
 * 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
Now that you've successfully made some changes to the MediaWiki extension, you want to submit them upstream to hopefully be merged back into the main code branch, and possibly deployed.


 * 1) Check your changes against the pre-commit chcklist
 * 2) Create a patch of your changes, following the 'submit your changes' guide.
 * 3) If you don't have an account already, create an account for yourself at http://bugzilla.wikimedia.org.
 * 4) FInd the bug opened for tracking code changes to this project - https://bugzilla.wikimedia.org/show_bug.cgi?id=34305
 * 5) Attach your patch to a comment in the bug, include some comments about what you've changed, and add the keywords 'patch' and 'need-review'


 * Since Bug 34305 is just an example bug and this is just an example extension, you might not actually get any review. But for any other bug or patch in Bugzilla, you will.

As you submit more and more patches and get more comfortable developing with MediaWiki, you will be able to apply for SVN commit access so you can directly make your changes in the repository, without having to make a patch.

REQUIRED READING
This reading is an absolute must for anyone making contributions to MediaWiki
 * Security for developers - Very important
 * Development policy
 * Coding conventions

Handy guides and documentation

 * Developer hub - A great launching point to a lot of documentation
 * How to become a MediaWiki hacker - Provides more in-depth details, including extensions
 * A much longer MediaWiki tutorial
 * List of simple extensions -- one step beyond this "example" extension.
 * https://bugzilla.wikimedia.org/buglist.cgi?keywords=easy - Easy bugs to get started with
 * Annoying Little Bug - Annoying bugs many people would love to see fixed. A great place to really dive in to MW development
 * Manual:Code - The MW code manual
 * Manual:MediaWiki architecture - An overview of MediaWiki's code architecture and history
 * ResourceLoader - Our framework for optimizing delivery of CSS, JavaScript, and other such resources