2020/08/29/MediaWiki SpecialPages

From Woozle Writes Code
Jump to navigation Jump to search
Codeblog

Dr. L needed a way to let students self-register on the private wiki I set up for him last week, so I'm taking the opportunity to write a MediaWiki extension I've been wanting for years now (and it kind of boggles my mind that this doesn't already exist) – something to allow entering and managing invite codes, with which a guest can create an account on a closed-registration wiki.

In the process, I found there were some things about the configuration files used when writing a SpecialPage that didn't seem very well documented, so I posted a comment over on the MediaWiki documentation site asking for confirmation of my guesses reverse-engineering: Manual_talk:Special_pages#better_documentation_for_key_identifier_strings

What I Posted

This isn't a help request so much as a "check me to make sure I'm not posting incorrect information". I'm working on a custom extension, and in between last night and this morning something changed which resulted in "No such special page" when I went to the page's URL from Special:SpecialPages -- although everything was still displaying properly there and in Special:Version. I figured that one out, but I thought it was high time to take some notes and, once I'm reasonably sure they're correct, post them here in MW's official documentation.

Anyone who does have answers, though, please feel free to chime in. ^.^

The documentation issues I'm trying to address:

  • There doesn't seem to be a clear list somewhere of all the bits that need to be defined properly in order for everything to work (and what is affected).
  • There's very little documentation of the JSON files, specifically what each key-string means or could mean. (This is partly JSON's fault for not permitting comments, which would be the obvious way to document examples.)

Crucial Bits List

Here's what I've got so far:

  • Knowns:
    • In extension.json:
      • The value of the "name": key is what is shown on the extension's entry on the Special:Version page.
      • Each element in "SpecialPages": { } defines a SpecialPage URL. The element name is the "X" in "Special:X" for each page.
        • (Tentative) This allows a single extension to define multiple Special pages, with the name of each element being the "X" for another Special:X. The element's value is the class to use.
        • (Tentative) For each X that points to a different class, that class can generate a corresponding entry in Special:SpecialPages.
        • Creating an entry for a class that doesn't exist will result in an error message like "Special:SpecialPages InvalidArgumentException from line 239 of <MediaWiki file path>/vendor/wikimedia/object-factory/src/ObjectFactory.php: Provided specification is not an array."[1]
    • In the primary PHP file:
      • the constructor should call parent::__construct('X');, where "X" must be the value of "Special:X".
      • whatever is returned by function getDescription() is displayed on Special:SpecialPages as the extension's description.
  • Unknowns:
    • In extension.json:

JSON files

  • extension.json (2020-09-18 There is actually documentation for this! Manual:Extension.json/Schema)
    • The descriptionmsg element seems to define the name of a key which should (or must?) appear in the i18n files.
  • i18n/ files:
    • All of the files in this folder are basically different-language translations of the same set of messages, so each one should (ideally) have the same set of keys.
    • Are there any specific entries (messages) which must be present, and mean something specific to MW? Or are they all pretty much up to the extension to use as desired?
    • qqq.json:
      • The qqq "language" is a "special" language which provides an explanation (in one language only), rather than display text, for each message. (Where is this actually used? Or is it just for human consumption? Does the name actually matter, or could a really thorough documenter have qqq-en.json, qqq-de.json, etc.?)
        • Each qqq element has a name of the form "[spkey]-[name]". where "[spkey]" refers to the Special Page's name -- but what, exactly, does [spkey] need to match?

Afterthoughts

What is the point of having separate methods for these two things?

  • determining what text is displayed for the extension's description in Special:SpecialPages (function getDescription())
  • determining what text is displayed for the extension's description in Special:Version ("name": in extension.json)

Why aren't they both defined in JSON, where they could both be i18nalized?

A thing which may or may not be mentioned in the official docs – the following code (when called from a SpecialPage-descended clas) sets both the <h1> title at the top of the page-content and the page-specific part of what is displayed in the browser's title-window:

        $mwoOut = $this->getOutput();
        $mwoOut->setPageTitle('Manage Invite Codes');

Footnote

  1. 2022-04-07 An example for clarity, determined while working on MakePage:
    	"SpecialPages": {
    		"MakePage": "makepage\\cSpecialPage"
    	},
    

    "MakePage" is the name of the SpecialPage (i.e. the full page name is Special:MakePage), and makepage\\cSpecialPage is the class which implements it. More generally:

    	"SpecialPages": {
    		"<SpecialPage name>": "<class that implements it>"
    	},
    

    See also htyp:MediaWiki/extensions, where real documentation should eventually go.