How to become a MediaWiki hacker/Extension Writing Tutorial
This page is outdated. |
- 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).
- 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
- Add the proper installation line to your
LocalSettings.php
file:wfLoadExtension( 'examples' );
Exercises
[edit]Exercise 1: Hello world
[edit]- 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.
- Add to the
execute
function inextensions/examples/includes/SpecialHelloWorld.php
the following line:echo 'hello world!';
echo
is a PHP command that prints out text and the content of variables. - 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.
- Create a new English message in
examples/i18n/en.json
that says "hello world". Eg:"examples-hello_world": "hello world!",
- 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.
- Remove the 'echo' line from
SpecialHelloWorld.php
. - Make the
execute
function inSpecialHelloWorld.php
use your new message. Eg:$out = $this->getOutput(); $out->addWikimsg( 'examples-hello_world' );
- 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.
- Change the 'hello world' message you created in
i18n/en.json
to use$1
instead of the word 'world':"examples-hello_world" : "hello $1!",
- 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. - Create a method in
SpecialHelloWorld.php
that will return a random name. You could create an array of a few possible names and usearray_rand()
function.public function getRandomName() { $ar = ['John', 'Mary', 'James', 'William']; return $ar[array_rand($ar)]; }
- Add the returned random name as the second parameter to the
addWikimsg
call in the execute method:$out->addWikimsg( 'examples-hello_world', $this->getRandomName() );
- 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.
- Make sure that the
$wgRequest
is available to you inside theexecute()
method inSpecialHelloWorld.php
:global $wgRequest;
- 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' ) );
- 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() ) );
- 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. - 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
- Security for developers - Very important
- Development policy
- Coding conventions
- Best practices for extensions
Handy guides and documentation
[edit]- Developer hub - A great launching point to a lot of documentation
- How to become a MediaWiki hacker - Provides more in-depth details, including extensions
- List of simple extensions -- one step beyond this "Examples" extension.
- New Developers - Software projects which welcome contributions (with mentorship)
- Annoying little bugs - Small tasks (without mentorship)
- 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