# Help:Parser function

A parser function is one of the double-brace structures that can be in a page, see also Help:Expansion. It returns a value based on at least one unnamed parameter, separated from the function name by a colon ":". There may also be additional parameters, which, like those of ordinary templates, are each preceded by "|". Parser functions differ by whether they have a leading hash character (#):

1. {{functionname: argument 1 | argument 2 | argument 3...}}
• Core parser functions (standardly built into MediaWiki); this is for backwards compatibility
• Optionally for parser function extensions
2. {{#functionname: argument 1 | argument 2 | argument 3...}}
• By default for parser function extensions, e.g., the ParserFunctions extension, to prevent collision with namespaces and interwiki prefixes

The distinction between parser functions and variables is technically that adding a pipe to the call of a variable causes the call to refer to a template with the same name, while excess parameters of a parser function are ignored. A not so strict distinction is also that the result of applying a variable usually depends on the time, the wiki, or the page, while the result of applying a parser function usually does not (although independence of the wiki requires that the same version of the parser function is installed, of course). The syntax is not necessarily different, except that variable names are always in capitals and never start with "#".

Compare the variable "PAGESINCATEGORY" and the parser function "formatnumber":

"{{PAGESINCATEGORY:Help}}" → "1" [1]
"{{PAGESINCATEGORY:Help|R}}" → "1" [2]
"{{formatnum:987654321.654321}}" → "987,654,321.654321" [3]
"{{formatnum:987,654,321.654321|R}}" → "987654321.654321" [4]

For each language, there is a file, like MessagesEn.php, that specifies, for each variable and parser function name, whether the name is case-sensitive.

Usually variables are case-sensitive and parser functions are not. To some variables, ":R" can be added ("raw" modifier), but, although now a parser function, the name is still case-insensitive. Exceptions are the function names DISPLAYTITLE:, PAGESINNAMESPACE:, PAGESINNS:, and DEFAULTSORT:, which are case-sensitive, and the variable name CURRENTTIME, which is case-insensitive.

MediaWiki's core parser functions are listed below and in Help:Magic words.

## Formatting

### LC

Makes the given text lowercase and removes newlines and spaces from the start and end.

• "{{lc: AbC dEf }}" → "abc def" [5]
• "{{lc: Ä Β Ç }}" → "ä β ç" [6]

### UC

Makes the given text uppercase and removes newlines and spaces from the start and end.

• "{{uc: AbC dEf }}" → "ABC DEF" [7]
• "{{uc: ä β ß ǰ}}" → "Ä Β ß ǰ" [8] (expected: Ä Β SS J̌)

### LCFIRST

Makes the first character lowercase and removes newlines and spaces from the start and end:

• "{{lcfirst: AbC dEf }}" → "abC dEf" [9]
• "{{lcfirst: Lower case}}" → "lower case" [10]

### UCFIRST

Makes the first character uppercase and removes newlines and spaces from the start and end:

• "{{ucfirst: AbC dEf }}" → "AbC dEf" [11]
• "{{ucfirst: upper case }}" → "Upper case" [12]

### URLENCODE

Removes newlines and spaces from the start and end, and converts the remaining text into URL-friendly format by replacing spaces with "+" and other URL formatting characters with their escaped equivalents:

• "{{urlencode:hello world ?&=#/:}}" → "hello+world+%3F%26%3D%23%2F%3A" [13]
• "{{urlencode: "#\$%&'()*,;?[]^{} }}" → "%22%23%24%25%26%27%28%29%2A%2C%3B%3F%5B%5D%5E%60%7B%7D" [14]
• "{{urlencode:<}}" → "%3C" [15] (with the old preprocessor not the percent code %3C of the symbol itself, but the percent code of the HTML code &lt;)
• "{{urlencode:>}}" → "%3E" [16] (with the old preprocessor not the percent code %3E of the symbol itself, but the percent code of the HTML code &gt;)
• "{{urlencode:{{!}}}}" gives "%7C" [17] ("|" needs to be given indirectly, using Template:!)

### ANCHORENCODE

For anchors within a page use {{anchorencode}} instead of {{urlencode}}. The results of a call to {{anchorencode}} are compatible with intra-page references generated for [[#link]]s, while {{urlencode}}-generated values are not necessarily so.

Note that (contrary to urlencode) the encoding made by "anchorencode", which uses the dot charactor as a prefix before a byte repesented in hexadecimal, is not fully reversible. "anchorencode" is then NOT suitable for passing query parameters. However, the encoding made by "urlencode" (which uses "%" characters) is not compatible with the more restricted character sets allowed in HTML and XML for ids. The two encodings also differ in the way they encode the space.

Compare:

• "{{anchorencode:Langue française}}" → "Langue_fran.C3.A7aise" [18] (valid only for anchors to sections in MediaWiki pages)
• "{{urlencode:Langue française}}" → "Langue+fran%C3%A7aise" [19] (for paths or query parameters in URLs, excluding anchors)

The encoding made by anchorencode is suitable to give anchor names within pages made with MediaWiki.

It is not guaranteed to work with other web sites: if you need to specify an anchor in a page not hosted on a server running MediaWiki, the anchor is not warrantied to work as expected. So, use "anchorencode" only for targetting a MediaWiki web site, such as those from the Wikimedia Foundation projects.

## NS

Gives the namespace name for a given namespace number or name:

Code
with Number
Code
with Name
Returns
with Number
Returns
with Name
{{ns:-2}} {{ns:media}} Media Media
{{ns:-1}} {{ns:special}} Special Special
{{ns:0}} {{ns:}}
{{ns:1}} {{ns:talk}} Talk Talk
{{ns:2}} {{ns:user}} User User
{{ns:3}} {{ns:user_talk}} User talk User talk
{{ns:4}} {{ns:project}} Meta Meta
{{ns:5}} {{ns:project_talk}} Meta talk Meta talk
{{ns:6}} {{ns:image}} File File
{{ns:7}} {{ns:image_talk}} File talk File talk
{{ns:8}} {{ns:mediawiki}} MediaWiki MediaWiki
{{ns:9}} {{ns:mediawiki_talk}} MediaWiki talk MediaWiki talk
{{ns:10}} {{ns:template}} Template Template
{{ns:11}} {{ns:template_talk}} Template talk Template talk
{{ns:12}} {{ns:help}} Help Help
{{ns:13}} {{ns:help_talk}} Help talk Help talk
{{ns:14}} {{ns:category}} Category Category
{{ns:15}} {{ns:category_talk}} Category talk Category talk
Namespaces 100 and higher are customized by each site
{{ns:100}} {{ns:hilfe}} Template:Ns:Hilfe
{{ns:101}} {{ns:hilfe_diskussion}} Template:Ns:Hilfe Diskussion

"{{ns:{{ns:12}}_talk}}" gives "Help talk" [20].

"{{ns:{{SITENAME}}}}" gives "Meta" [21].

"{{ns:{{ns:8}}_talk}}" gives "MediaWiki talk" [22].

"{{ns:{{ns:8}} talk}}" gives "MediaWiki talk" [23].

See Help:Variable for more canonical names like "project" and "talk".

### NS:1

"{{ns:{{ns:0}}_talk}}" gives "Template:Ns: talk" [24], just as {{ns:_talk}} gives Template:Ns: talk [25]. The canonical name for the talk namespace of articles is "talk" and not "_talk". Appending "_talk" to the namespace name works for all but the main namespace.

The following constructs work:

• "{{ns:{{ns:0}} talk}}" gives "Talk" [26].
• {{ns:01}} gives Talk [27].
• {{ns:+1}} gives Talk [28].
• {{ns:TALK}} gives Talk [29].
• "{{ns:{{ns:1}}}}" gives "Talk" [30].

### ns:0 gives null string

{{ns:0}} gives [31], an empty string. This is often handy, and less vulnerable to vandalism by a compromised administrator account, than a template void or similar mechanism.

The cryptic magic word __END__ is no longer supported. It formerly allowed for trailing whitespace to be included in the saved page, but was removed in revision 19213.

In constructs like {{ {{#if: {{{T|}}} | {{{T}}} | ns:0}} }}, where parameter T is normally the name of a template to be evaluated, but can be undefined or empty, {{ns:0}} is then a clean empty string. Without it, {{}} would result in {{}}.

"{{ {{#if: {{{T|}}} | {{{T}}} | ns:0}} }}" gives "" [32].

### Empty or invisible section headers.

The wikitext line

=== {{ns:0}} ===


creates an entry in the TOC coded in the output HTML as

<li class="toclevel-2"><a href="#"><span class="tocnumber">2.4</span> </a></li>


attempting but failing to link to the null anchor

<p><a name=""></a></p>


and with an edit link similar to this:

[<a href="/w/index.php?title=Help:Parser_function&amp;action=edit&amp;section=12">edit</a>]


The next line is === {{ns:0}} ===. Note the edit link to the right.

An empty section title (with an edit link to the right) as above is obtained using, in this case, === {{ns:0}} ===. This is dubious, but arguably better than using the same trick to get invisible section headers twice on a page. At least /* {{ns:0}} */ makes sense in the edit history, if there's only one section using this particular trick.

As shown in the table of contents, this and similar tricks result in non-functional links. In conjunction with __NOTOC__ it's less harmful, and maybe useful to get edit links for invisible sections with categories and interlanguage links. Other possibilities for different invisible section headers:

1. === __NOTOC__ ===
2. === ===
3. === &nbsp; ===
4. === &#160; ===

## URLs etc.

 {{localurl:fullpagename}} /wiki/Fullpagename {{localurl:page|query=x}} /w/index.php?title=Page&query=x {{localurl:a&b! c}} {{localurle:a&b! c}} /wiki/A%26b!_c /wiki/A%26b!_c {{urlencode:a&b! c}} a%26b%21+c {{anchorencode:a&b! c}} a.26b.21_c {{fullurl:fullpagename}} //meta.wikimedia.org/wiki/Fullpagename {{fullurl:ab}} //meta.wikimedia.org/wiki/Ab {{fullurl:a b}} //meta.wikimedia.org/wiki/A_b {{fullurl:ab|u=v}} //meta.wikimedia.org/w/index.php?title=Ab&u=v {{fullurl:m:a b|u=v}} //meta.wikimedia.org/wiki/a_b?u=v {{fullurl:m:ab|u=v}} //meta.wikimedia.org/wiki/ab?u=v {{fullurl:a b|u=v}} //meta.wikimedia.org/w/index.php?title=A_b&u=v {{fullurl:a b|u=v w}} //meta.wikimedia.org/w/index.php?title=A_b&u=v w {{fullurl:a&b!|u=v}}   //meta.wikimedia.org/w/index.php?title=A%26b!&u=v {{fullurle:a&b!|u=v}}  //meta.wikimedia.org/w/index.php?title=A%26b!&u=v

Note that with the interwiki prefix, the format "wiki/" is used even for edit pages etc., while it does not write the page name in canonical form.

For interwiki links, localurl and fullurl give the same result:

 {{localurl:w:a}} {{fullurl:w:a}} //en.wikipedia.org/wiki/a //en.wikipedia.org/wiki/a

The parser function localurl: replaces spaces by underscores and special characters by escape codes, e.g., {{localurl:a !}} gives /wiki/A_!. The main purpose was to create a link to a given page in external link style in the same project or a project that uses the same string in the URL between the server name and the page name. This function is now better served by less verbose fullurl: constructs, {{fullurl:page}} is a shorthand for {{SERVER}}{{localurl:page}}.

Both fullurle: and localurle: performed additional character escaping on the resulting link, but no example is known where that still has any additional effect.

Note that fullurl: and localurl: don't encode special characters and spaces in the optional query-string parameter. At least for spaces this will result in broken URLs:
{{fullurl:m:Special:Contributions|target=Jimbo Wales&limit=10}}
//meta.wikimedia.org/wiki/Special:Contributions?target=Jimbo Wales&limit=10

With target={{urlencode:Jimbo Wales}}&limit=10 as query-string it works:
//meta.wikimedia.org/wiki/Special:Contributions?target=Jimbo+Wales&limit=10

The new urlencode: encodes spaces as "+", not "_" or the generally supported "%20", this might have interesting effects, take care. Leading and trailing spaces are stripped, but all internal spaces are preserved: {{urlencode:  @  !  }} yields %40++%21.

For obvious reasons, encoding "}}" or "|" cannot work directly. Don't encode "=", "&", or ";" in structured query-strings unless you really want them.

### Example

Say you want to create a link in a template to the block log for blocked usernames -> "{{fullurl:Special:Log/block|user=User:{{{1}}} }}". This won't work with spaces in the name like "Example blocked user" (unless they are manually replaced with underscores), as you'd get: "//meta.wikimedia.org/w/index.php?title=Special:Log/block&user=User:Example blocked user", so what you can do is escape it with: "{{fullurl:Special:Log/block|user=User:{{urlencode:{{{1}}}}} }}", giving you "//meta.wikimedia.org/w/index.php?title=Special:Log/block&user=User:Example+blocked+user".

Also, the magic words for page name like {{PAGENAME}} {{FULLPAGENAME}} etc all have 'escaped' versions: {{PAGENAMEE}} {{FULLPAGENAMEE}} etc.

## #language:

{{#language:code}} gives the local language name of selected IETF BCP 47 language codes (see notes below), otherwise it returns the input value as is.

{{#language:da}} gives dansk [33]
{{#language:fo}} gives føroyskt [34]
{{#language:zh}} gives 中文 [35]
{{#language:zh-min-nan}} gives Bân-lâm-gú [36]
{{#language:ang}} gives Ænglisc [37]
{{#language:tlh}} gives tlh [38] (missing, incomplete list)
{{#language:frr}} gives Nordfriisk [39] (missing, introduced 2006)
{{#language:mw}} gives mw [40] (no language code as of 2006)
{{#language:hu}} gives magyar [41]

This function will replace Template:N local and some of the Special:Prefixindex/Template:Lang name - templates. For actually supported alpha2 and alpha3 codes see Template:Sttnw; the 27*26*26 template calls on that page may take some time to render.

Notes
The IETF BCP 47 standard is currently defined in RFC 5646 (obsoleting the former RFC 4646 and the older RFC 3066), along with the IANA registry for standard language subtags themselves, some other RFCs for the policy for registering new standard tags and subtags in the registry, and some informative RFCs documenting the evolution and migrations occuring in the registry; or the lookup and interpretation of tagged contents.
An error is to document IETF RFC document numbers instead of BCP standard track numbers, when none of the RFCs contain the language codes themselves.
Another frequent error is the confusion of BCP 47 language tags and ISO 649 language codes : they are not equivalent. In addition ISO 649 is not sufficient for software localisation (including in MediaWiki) and it would cause compatibility problems. MediaWiki preferably uses BCP 47 because it is a software that generates contents that will ultimately be interchanged with other softwares, notably on the Internet with the HTML and XML standards or in most programming languages (where BCP 47 language tags are normative, but not ISO 649 codes !!!).
However, for historical reasons, MediaWiki also defines additional codes that are not conforming to any standard (and sometimes in conflict with them in some old Wikimedia projects). These old codes are retained when they are used as subdomain names (via interwiki codes), but should not be used anywhere for tagging the generated HTML or XML contents themselves. Progressively these old codes will be migrated to standard BCP 47 language tags if possible; if there's no standard BCP 47 taf, conforming private-use tags should be used (but valid ISO 649 codes that are not conforming to BCP 47 should never be used until they are registered in the IANA database to make them valid and stable).
Basically, the conforming BCP 47 language tags are formed by using standard subtags contains most (but not all) standard ISO 649 language codes, with some extensions from ISO 15924 for script codes, from ISO 3166-1 country codes and UN M.49 continental regions codes, and some other extensions needed dor specific locales; it also maintains upward compatibility with former versions of the current RFCs, but the IANA registry may deprecate some of them (without deleting them and making them invalid), when they are now considered ambiguous and would not be accepted in the registry if they were defined today under the current policy of the standard). Note also that some BCP 47 language tags have been defined with the former policy, even though they are not really languages but wide language families. Their usage for localization (and notably for translations) should be discouraged.
When a standard BCP 47 language tag is matching an ISO ISO 649 language code and the IANA registry does not indicate that the tag is deprecated, some other information about the language will be defined in ISO 649-3 or ISO 649-5 about the type of language code (but the converse is not true because some valid ISO 649 language codes are not valid as standard BCP 47 language tags). Some language tags are also valid in BCP 47 due to upward compatibility, even if the associated language code in ISO 649 has been deleted or replaced by other codes, or merged into another code (the IANA registry normally maintains an history of such cases and suggests the best replacement to use instead, if possible, according to the most frequent usage of the language tag or subtag, when it was deprecated).
For a complete list of standard language subtags (all of them, including grandfathered codes registered in past versions, but excepting all conforming private-use subtags and those reserved for future use as described in standard RFCs), and normative information about their possible deprecation and possible replacement, see the IANA registry.

## Pages in category

Word Example Example results Explanation
{{PAGESINCATEGORY:category}}
{{PAGESINCATEGORY:category|R}}
{{PAGESINCATEGORY:User en}}
{{PAGESINCATEGORY:User en|R}}
5,133
5133
[MW1.13+] Returns the number of pages in a given category. Including sub-category pages and file description pages.
{{PAGESINCAT:category}}
{{PAGESINCAT:category|R}}
{{PAGESINCAT:User en}}
{{PAGESINCAT:User en|R}}
5,133
5133
[MW1.13+] Alias of PAGESINCATEGORY.

## #invoke

On wikis with a Module namespace there is the parser function #invoke:

{{#invoke:a|f}}


which invokes Module:A. While the parser function call can have more parameters they are typically not needed, because typically the call is put in a template, and on the page that calls the template the wikitext produced by the template can depend on the parameter definitions in the template call, even if these parameters are not explicitly referenced in the template, i.e., neither used there nor explicitly passed on to the module. This is because the module can access these parameter definitions through the function getParent (see Receiving template arguments and Parent frame access). Moreover, the module can not only (like a template) find out whether the value of a known parameter is defined, and if so, what the value is, but even find out the names of the defined parameters, whatever they are.

## Use of result

The wikitext resulting from the expansion of a parser function call, like that from expansion of a variable or template call, and like a template parameter value, can be used in the following ways:

* the name of a template: {{ {{lc:ABC}}}}
* the name of a variable: {{ {{uc:currenttime}}}}
* the name of a parser function: {{ {{uc:lc}}:ABC}}
* the name of a template parameter: {{t2|{{#expr:3-1}}=a}}
* the value of a template parameter: {{t2|{{#expr:3-1}}}}
* a template parameter default value: {{{1|{{#expr:7-2}}}}}
* the name of a switch parameter: {{#switch:2|{{#expr:3-1}}=a}}
* the value of a parser function parameter: {{#ifeq:{{lc:AbC}}|abc|yes}}
* the target or label of an internal link: [[{{lc:ABc}}|{{uc:ABc}}]]
* the target or label of an external link: [http://{{lc:Example.Org}} {{uc:Example}}]


gives:

• the name of a template: essai de PAGE:Sandbox
• the name of a variable: 07:57
• the name of a parser function: abc
• the name of a template parameter: parameter 1 is "{{{1}}}", parameter 2 is "a"
• the value of a template parameter: parameter 1 is "2", parameter 2 is "{{{2}}}"
• a template parameter default value: 5
• the name of a switch parameter: a
• the value of a parser function parameter: yes
• the target or label of an internal link: ABC
• the target or label of an external link: EXAMPLE.ORG

If the expanded wikitext contains characters, which, if put explicitly in the wikitext, are significant for parsing it, these characters are treated as plain text, because for a given page there is only one parsing phase. For example for the character "=":

* a template parameter definition ( ''name'' = ''value'' ): {{pab|{{lc:AB=CD}}}}
* a switch parameter definition ( ''name'' = ''value'' ): {{#switch:ab|{{lc:AB=CD}}}}


gives:

• a template parameter definition ( name = value ): {{{ab}}}
• a switch parameter definition ( name = value ): ab=cd

Wikitext inside XML-style tags is not expanded:

• ${{#expr:3-1}} \over 3$ gives ${#expr:3-1}$

• {{#tag:math|{{#expr:3-1}}\over 3}}` gives $2 \over 3$ [42]

## Expansion

The first step in expanding any wikitext is identifying the templates, parser functions, variables and parameters from the braces, pipes and semicolons. For a parser function the next step is expanding the wikitext for the name of the parser function.

Suppose, for example, that it is #ifexpr. Then the next step is expanding the condition. Based on that, either the wikitext for the then-part or that for the else-part is expanded.

This is illustrated with {{#ifexpr:1|{{ta}}|{{tb}}}} {{#ifexpr:0|{{tc}}|{{td}}}} giving start-pqr-end start-def-end. A page with this wikitext transcludes ta and td only (with the old preprocessor also transcluded tb and tc).

## Interpretation of a parser function as a template

In some cases, a "wrong" parser function call is interpreted as a template call, which results in an entry in the templatelinks table, giving an entry in the list of pages included in a page (on the edit box of the source page) and What links here of the target page.

This applies, e.g., for localurl and fullurl if the parameter is not a valid page name, while "Template:localurl:" and "Template:fullurl:" followed by the parameter is. This is the case if the parameter is a namespace prefix followed by a colon, e.g.:

This entry in the templatelinks table occurs even if the result produced is not rendered due to a conditional parser function. This may occur in practice using, e.g.,:

• {{ #if:{{{1|}}}|..{{ fullurl:Template:{{{1|}}} }}..}}
• {{ #if:{{{1}}}|..{{ fullurl:Template:{{{1}}} }}..}} in the case that the parameter is equal to the empty string; it does not occur if the parameter is undefined, because "Template:fullurl:Template:{{{1}}}" is not a valid page name.

Thus, the list of templates transcluded in a page may be polluted with the entries of the non-existing template Template:fullurl:Template: and similarly for other namespace names instead of the second "Template", and for "localurl" instead of "fullurl". A remedy is, e.g.,:

• {{ #if:{{{1|}}}|..{{ fullurl:Template:{{#if:{{{1}}}|{{{1}}}|[]}} }}..}} because "Template:fullurl:Template:[]" is not a valid page name.