Learning how to share what you learnt
Tags: mediawiki, lua, php, github
Published: 2020-04-17 14:50:01

My main project at the moment is a custom MediaWiki installation that hosts a hyper-textual guide to *Star Trek*. It is something similar to the widely-known *Memory Alpha*, surely in a smaller size, but it is in italian language and based on a standard modern version of MediaWiki. Furthermore, this project is heavily integrated with *WikiBase*, a substantial extension to MediaWiki that provides database-like capabilities and it is the cornerstone of open data for *Wikipedia* being the base of [*WikiData*](https://www.wikidata.org/wiki/Wikidata:Main_Page).

## MediaWiki and LUA
Basic usage of data from WikiBase is very easy, but any complex access to data needs custom coding in LUA. LUA is provided as a language for customising MediaWiki through an [extension called *Scribunto*](https://www.mediawiki.org/wiki/Extension:Scribunto). WikiBase comes with a LUA Scribunto interface that allows easy manipulation.
[There is a manual](https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua) on how to use the LUA interface that lists and explain all the object model, but IMHO fails in providing enough examples.
So I started the painful experience, so familiar to all developers, of trials and errors till I found a way to make everything work.

While the LUA code I was writing was specific to my project, I started thinking it could also be made more generic and maybe useful to other users, so i thought a way to share it.
Being on a public Wiki, the code was accessible to anyone (but editable only to members, just as a passing comment) so already *shared*, in sense. Nevertheless, the truth is, in practical terms, that our wiki is about a niche product of a niche of the entertainment industry; incidentally the wiki is also written in italian, reducing its potential readership even more.
I needed a better idea.

## How to share
*WikiTrek* is a [GitHub "organization"](https://github.com/WikiTrek) already, so the first thing I thought was to publish the LUA code on a dedicated repository. At first I started to copy and paste the code manually, so each time I made a modification to LUA code, I copied and pasted it.
It was very inefficient and prone to errors.

A better approach would have been to transfer data automatically from the wiki pages to GitHub.
First important thing was not to reinvent the wheel, so I started looking for a ready-to-use PHP library to interact with GitHub and found [PHP GitHub API](https://github.com/KnpLabs/php-github-api) pretty soon. It is an excellent library to perform any kind of operations on GitHub using ready-made PHP classes.

## Finding the right way
So I started playing around with *PHP GitHub API* and, in a couple of hours (documentation and examples of that library might benefit from some work, but this is another story), I had a proof-of-concept small application to manipulate GitHub via that API.
My original plan was to write a [MW Maintenance script](https://www.mediawiki.org/wiki/Manual:Maintenance_scripts) and run it on the server periodically using *cron* or maybe MW own scheduler.
The more I looked into this solution, though, the more complicated it became.
After a few days of alternatively banging my head against the problem and thinking about it, I came up with a different solution.

I started looking into [*extension* development](https://www.mediawiki.org/wiki/Manual:Developing_extensions) and found out there is a class of extensions using [*Hooks*](https://www.mediawiki.org/wiki/Manual:Hooks) allowing to inject custom PHP code at certain event. Most prominent example of these events is [`PageContentSaveComplete`](https://www.mediawiki.org/wiki/Manual:Hooks/PageContentSaveComplete) and that was all I needed: by intercepting a page when it is saved, I could have taken the content to send it to GitHub.
Bingo.

## Building the extension
First step was to familiarise myself with the extension development: MediaWiki documentation on the topic is vast and – as unfortunately often happens with that project – not completely structured.
I found the two most important thing to master:
1. the intricacy of [Extension registration](https://www.mediawiki.org/wiki/Manual:Extension_registration) using the `extension.json` file and
2. the handling of custom settings via [configuration variables](https://www.mediawiki.org/wiki/Manual:Configuration_for_developers)

Once I understood the basics of extension development, I had to tackle some issues about the on the working of the extension:
* I wanted only *some* pages to be transferred, so I found a way to select the pages belonging to `Module:` namespace only
* All the pages with code on them ends up in the `Module:` namespace, so I needed to select only specific pages, otherwise I would have copied code belonging to other extensions or template or whatever, most likely code non even written by contributors to the site. I resolved to do so by introducing a custom keyword to look for in the page.
* I implemented a mechanism to *not* save the pages if the edit is marked as "Minor"

Firstly I hard-coded all of the above for testing purpose: by the end of the projects, I made all options user-customisable variables that can be handled in `Localsettings.php`

## Closing words
The result of all this effort is an extension that I called [*PageToGitHub*](https://github.com/lucamauri/PageToGitHub) (or *P2G*, in brief). I don't expect this to be used by someone else as it address a very specific feature that is hardly to be found elsewhere.
Nevertheless I am very satisfied with it because, apart of solving the original issue I had, the journey to create it helped me to improve my (otherwise *very* limited) PHP skills and guided me to better understand inner MediaWiki mechanisms.
Beside, of course, allowing me to write this post and start my humble contribution to DEV community.