Mastering MediaWiki Parser Functions: Essential Techniques for Advanced Users
Why “parser functions” matter (even if you’ve been tinkering with MediaWiki for ages)
When you stare at a wikitext page that magically fills in dates, makes conditional tables, or pulls data from another article, you’re basically watching parser functions at work. For newcomers they look like sorcery; for seasoned editors they’re just another toolbox. This post pulls together the tricks that most “advanced” users either overlook or keep hidden in personal wikis.
Quick refresher – what’s a parser function?
In MediaWiki jargon a parser function is a special construct that starts with # and behaves like a tiny, inline program. It gets evaluated while the wikitext is parsed, before the output is finally rendered. Think of it as a macro that can read variables, do simple math, or decide what to show.
Basic syntax
{{#function_name:parameter1|parameter2|…}}Everything after the colon up to the closing braces is split on the pipe (|) character; the first piece is the function name, the rest are arguments.
Effective grouping – using variables
Variables are the unsung heroes behind clean, reusable markup. The two main families are {{#vardefine}} / {{#vardefineecho}} (temporary) and the long‑standing “magic words” like {{FULLPAGENAME}}. Here’s a small pattern I use to avoid repeating a long article name:
{{#vardefine:page|{{FULLPAGENAME}}}}
* Link: [[{{#var:page}}]]
* Talk: [[Talk:{{#var:page}}]]
Notice the double‑braces around #var. It’s a tiny detail that trips up newbies: the variable expansion happens after the outer braces are stripped, so you really need both.
Scoping tricks
Variables defined in a #if block stay visible afterwards – an easy way to propagate a value without polluting the global namespace. For instance:
{{#ifexist:{{FULLPAGENAME}}/Data|
{{#vardefine:data|{{#subpagename:Data}}}}
}}
The data for this page is {{#var:data}}.
If the subpage doesn’t exist, #vardefine never runs, and #var:data stays empty. That’s a clean “optional” pattern.
Conditional logic – #if, #ifeq, #iferror
The simplest conditional is #if. It checks whether its first argument is non‑empty. But most of the time you need to compare two strings, numbers or even the result of an expression. Enter #ifeq and #iferror.
Example – show a warning when a user forgets to fill a required field in a template:
{{#if:{{{title|}}}||
You must provide a title.
}}
And a numeric check (useful for stats pages):
{{#ifeq:{{#expr:{{{score|0}}} >= 100}}|1|
{{#iferror:{{#expr:{{{score|0}}}+0}}|
Score isn’t a number.
|
Score is below the threshold.
}}
}}
Notice the use of #expr to do arithmetic, and the double‑pipe that separates the “true” and “false” branches.
Switching between multiple values – #switch
If you have three or more alternatives, #switch beats stacked #if calls both in readability and performance.
{{#switch:{{{type|default}}}
|article = {{#ifexist:{{FULLPAGENAME}}/Article|Article content}}
|image = {{#ifexist:{{FULLPAGENAME}}/Image|Image preview}}
|default = Unknown type.
}}
Each = clause can itself contain other parser functions, which makes #switch a tiny control‑center for almost any “type‑based” template.
Expressions – #expr
If you need math or logical operators, #expr is your go‑to. It supports:
- Arithmetic:
+,-,*,/,mod - Comparison:
=,!=,<,> - Logical:
and,or,not - String functions:
strlen,substr
Example – creating a progress bar based on a percentage:
{{#expr:
{{#if:{{{percent|}}}|{{{percent}}}|0}}
}}
That one‑liner just sanitises the input (defaults to 0) before feeding it to a CSS class or a template that draws the bar.
Namespace and page‑related functions
Sometimes you need to slice a page name: get the title, the namespace, or the URL‑encoded version. MediaWiki offers a set of so‑called “title‑functions”:
#titleparts– returns individual parts (namespace, title, subpage, etc.)#urlencode– makes a string safe for URLs#urlencodepath– similar but keeps slashes#rel2abs– converts a relative link to an absolute one
Use case – building a link to the edit form of a related article:
{{#ifexist:{{FULLPAGENAME}}/Reference|
[{{fullurl:{{FULLPAGENAME}}/Reference|action=edit}} Edit reference]
}}
The fullurl magic word (not a parser function but a sibling) couples nicely with #urlencode when you need to pass parameters.
Formatting helpers – #tag, #timel
Outputting raw HTML is frowned upon, but #tag lets you safely emit a tag with proper escaping:
{{#tag:div|Content here|class=note}}
And for timestamps, #timel can format a Unix timestamp according to a locale‑specific pattern. It’s handy when you want a “last‑updated” line that respects the reader’s language settings.
Transclusion modifiers – includeonly, onlyinclude, noinclude
These aren’t parser functions per se, but they dictate whether a template’s markup is seen by the page that includes it. A quick cheat‑sheet:
<includeonly>…</includeonly>– shown only when transcluded, never on the template page itself.<onlyinclude>…</onlyinclude>– everything else is stripped; only the enclosed part appears on transclusion.<noinclude>…</noinclude>– shown on the template page, but never when the template is used elsewhere.
Mixing these with parser functions yields compact “template‑as‑API” constructs. For example, a “data‑sheet” template might expose just a table (wrapped in onlyinclude) while keeping documentation hidden with noinclude.
Advanced pattern – Cascading defaults
One common pain point is letting a user override a default, yet providing fall‑backs without sprinkling #if everywhere. Here’s a neat trick that combines #var and #ifexist:
{{#vardefine:color|{{#ifexist:{{FULLPAGENAME}}/Color|{{#subpagename:Color}}|blue}}}}
This text follows the chosen colour.
If the subpage Color exists, its content wins; otherwise we fall back to “blue”. The pattern works for any setting – icons, language strings, even CSS snippets.
Performance notes – don’t over‑nest
Parser functions are executed sequentially. Deeply nested calls (#if inside #expr inside #switch…) can slow down rendering, especially on high‑traffic wikis. A rule of thumb: if a construct feels like a “spaghetti” of pipes, consider splitting it into a small auxiliary template.
Also, avoid using #expr for simple string checks; #if does the job faster. The MediaWiki engine logs “expensive parser function” warnings for cases that cross a hidden threshold.
Real‑world example – a dynamic “infobox”
Below is a compact infobox template that pulls a page’s subtitle, an optional image, and a stats table, all driven by parser functions. It demonstrates conditional sections, variable scoping, and safe HTML output.
{{#ifexist:{{FULLPAGENAME}}/Subtitle|
{{#vardefine:subtitle|{{#subpagename:Subtitle}}}}
}}
{{#ifexist:{{FULLPAGENAME}}/Image|
{{#vardefine:image|{{#subpagename:Image}}}}
}}
{{#ifexist:{{FULLPAGENAME}}/Stats|
{{#vardefine:stats|{{#subpagename:Stats}}}}
}}
{{#tag:table|{{#if:{{#var:subtitle}}|
{{#tag:tr|{{#tag:td|{{#var:subtitle}}|colspan=2}}}}
}}
{{#if:{{#var:image}}|
{{#tag:tr|
{{#tag:td|{{#var:image}}|width=100}}
{{#tag:td|{{#var:stats}}}}
}}
|
{{#tag:tr|{{#tag:td|{{#var:stats}}|colspan=2}}}}
}}
|class=infobox
}}
What’s happening?
- We check for the existence of three optional subpages (subtitle, image, stats).
- Each existing subpage gets stored in a temporary variable.
- The final table is built with
#tagto avoid raw HTML. - Conditional rows appear only when their corresponding data is present.
The result is a tidy infobox that auto‑adjusts its layout without any manual editing.
Debugging tip – #show
When a parser function misbehaves, sprinkle #show into the markup to dump the value of a variable or the result of an expression. Example:
{{#show:{{#var:color}}}}
The output appears on the rendered page, letting you verify the exact string that the parser sees. Once you’re sure, simply remove the line.
Wrapping up – a mental checklist
- Scope first. Declare temporary variables early, then reuse them.
- Prefer #if / #ifeq over long #expr. Faster and clearer for simple checks.
- Group alternatives with #switch. Keeps templates readable.
- Escape HTML with #tag. Avoid raw tags unless you trust the source.
- Test with #show. Quick sanity checks save hours of hunting.
Mastering these patterns turns a cluttered, “hand‑rolled” wikitext page into a maintainable, self‑documenting component. The next time you need a dynamic list, a conditional banner, or a multi‑step calculation, reach for the parser function toolbox first – you’ll thank yourself when the page loads in a flash and future editors can read your logic without grimacing.