Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/wikimedia/mediawiki/llms.txt

Use this file to discover all available pages before exploring further.

Magic words are localizable keywords in wikitext that the parser recognizes and replaces with dynamic values or that control parser behavior. From magicword.md:
Magic words are localizable keywords used in wikitext. They are used for many small fragments of text, including the names of parser functions, the names of variables, double-underscore behavior switches, and image link parameter names.
Each magic word has a unique ID, a case-sensitivity flag, and a list of synonyms. The MagicWord class matches wikitext against these synonyms by compiling them into a regular expression.

Types of magic words

Behavior switches

Double-underscore keywords that toggle parser behavior. Examples: __TOC__, __NOTOC__, __NOINDEX__, __FORCETOC__. They produce no output but modify how the page is rendered.

Variables

Transclusion-style keywords that expand to dynamic values. Examples: {{PAGENAME}}, {{CURRENTDAY}}, {{NUMBEROFARTICLES}}. They take no arguments.

Parser functions

Variable-style keywords that accept arguments: {{urlencode:foo bar}}, {{#if: condition | then | else }}. The #-prefixed form is conventional for extension-defined functions.

Image parameters

Keywords used inside [[File:...]] syntax to control image rendering: thumb, right, left, center, frameless.

Core variables

Core magic variables are implemented in CoreMagicVariables. Some variables have cache TTL hints because their values change over time:
// Map of (word ID => cache TTL hint in seconds)
private const CACHE_TTL_BY_ID = [
    'currenttime'          => 3600,
    'localtime'            => 3600,
    'numberofarticles'     => 3600,
    'numberoffiles'        => 3600,
    'numberofedits'        => 3600,
    'numberofusers'        => 3600,
    'numberofactiveusers'  => 3600,
    'numberofpages'        => 3600,
    'currentversion'       => 86400,
    'currenttimestamp'     => 3600,
    'localtimestamp'       => 3600,
    'pagesinnamespace'     => 3600,
    'numberofadmins'       => 3600,
    'numberingroup'        => 3600,
];
Core parser functions without the # prefix (registered via Parser::SFH_NO_HASH) include:
ns, nse, urlencode, lcfirst, ucfirst, lc, uc,
localurl, fullurl, canonicalurl, formatnum, grammar,
gender, plural, padleft, padright, anchorencode,
defaultsort, filepath, pagesincategory, pagesize,
pagename, fullpagename, subpagename, basepagename,
pageid, revisionid, revisionday, revisionyear,
revisiontimestamp, namespace, talkspace, ...

Registering magic words in an extension

Step 1: create the i18n magic words file

Create a file named ExtensionName.i18n.magic.php. The array is keyed by language code, then by magic word ID. Index 0 is the case sensitivity flag (0 = case-insensitive, 1 = case-sensitive); subsequent indices are synonyms.
<?php

$magicWords = [];

$magicWords['en'] = [
    // Case insensitive — 0 means case-insensitive
    'mag_custom' => [ 0, 'custom' ],
];

$magicWords['es'] = [
    'mag_custom' => [ 0, 'aduanero' ],
];

Step 2: register the file in extension.json

{
    "ExtensionMessagesFiles": {
        "ExtensionNameMagic": "ExtensionName.i18n.magic.php"
    },
    "Hooks": {
        "ParserFirstCallInit": "MyExtensionHooks::onParserFirstCallInit"
    }
}
The key in ExtensionMessagesFiles (e.g. "ExtensionNameMagic") must be globally unique. It must not be used by any other extension.

Step 3: implement the parser function hook

<?php

class MyExtensionHooks {
    public static function onParserFirstCallInit( $parser ) {
        $parser->setFunctionHook(
            'mag_custom',
            [ self::class, 'expandCustom' ]
        );
        return true;
    }

    public static function expandCustom( $parser, $var1, $var2 ) {
        return "custom: var1 is $var1, var2 is $var2";
    }
}
This registers {{custom: arg1 | arg2 }} (English) and {{aduanero: arg1 | arg2 }} (Spanish) as equivalent.

Behavior switches

Behavior switches use double-underscore syntax and are matched by the MagicWord class. To add a custom behavior switch:
1

Define the magic word

Add the ID and synonyms to your .i18n.magic.php file:
$magicWords['en'] = [
    'mag_nosidebar' => [ 0, '__NOSIDEBAR__' ],
];
2

Register the behavior switch ID

Use the GetDoubleUnderscoreIDs hook to add your ID to the list of recognized behavior switches:
public static function onGetDoubleUnderscoreIDs( array &$ids ): void {
    $ids[] = 'mag_nosidebar';
}
In extension.json:
{
    "Hooks": {
        "GetDoubleUnderscoreIDs": "MyExtensionHooks::onGetDoubleUnderscoreIDs"
    }
}
3

React to the behavior switch

Check ParserOutput in your hook to detect whether the switch was used:
// In an OutputPageParserOutput hook, or similar:
public static function onOutputPageParserOutput(
    OutputPage $out,
    ParserOutput $parserOutput
): void {
    if ( $parserOutput->getPageProperty( 'mag_nosidebar' ) !== null ) {
        // Page used __NOSIDEBAR__, apply the effect
    }
}

Variables (magic variables)

To register a custom variable that expands to a dynamic value, use the GetMagicVariableIDs hook plus ParserGetVariableValueSwitch:
// Register the variable ID
public static function onGetMagicVariableIDs( array &$ids ): void {
    $ids[] = 'mag_customvar';
}

// Provide its value during parsing
public static function onParserGetVariableValueSwitch(
    Parser $parser,
    array &$variableCache,
    string $magicWordId,
    ?string &$ret,
    PPFrame $frame
): void {
    if ( $magicWordId === 'mag_customvar' ) {
        $ret = 'hello from custom variable';
        $variableCache[$magicWordId] = $ret;
    }
}
In extension.json:
{
    "ExtensionMessagesFiles": {
        "MyExtensionMagic": "MyExtension.i18n.magic.php"
    },
    "Hooks": {
        "GetMagicVariableIDs": "MyExtensionHooks::onGetMagicVariableIDs",
        "ParserGetVariableValueSwitch": "MyExtensionHooks::onParserGetVariableValueSwitch"
    }
}
And in the magic words file:
$magicWords['en'] = [
    'mag_customvar' => [ 0, 'CUSTOMVAR' ],
];
The variable is then used in wikitext as {{CUSTOMVAR}}.

MagicWord matching API

The MagicWord class provides methods for matching text against a magic word:
$mwFactory = MediaWikiServices::getInstance()->getMagicWordFactory();
$mw = $mwFactory->get( 'redirect' );

if ( $mw->match( $text ) ) {
    // $text is a redirect keyword in the content language
}

// Match and remove from a string
if ( $mw->matchAndRemove( $text ) ) {
    // $text was modified in-place, keyword stripped
}

// Match any magic word from a list
$mwArray = $mwFactory->newArray( [ 'redirect', 'img_right', 'img_left' ] );
$matched = $mwArray->matchAndRemove( $text );
Avoid extracting raw synonym lists from MagicWord and writing special-case string comparisons. Add a new match()-style method to the MagicWord or MagicWordArray class if the built-in matching methods don’t cover your use case.

Build docs developers (and LLMs) love