Exploring MediaWiki Parser Functions for Advanced Templating
When you glance at a Wikipedia page you probably never think about the invisible machinery that decides whether a table shows a footnote or a badge pops up next to a name
Why Parser Functions Matter in MediaWiki
When you glance at a Wikipedia page you probably never think about the invisible machinery that decides whether a table shows a footnote or a badge pops up next to a name. That machinery is, for the most part, a handful of parser functions tucked inside MediaWiki's wikitext engine. In the hands of a seasoned template author, they become the difference between a static stub and a page that reacts to the very data you feed it.
Parsing the Basics
At its core, a parser function starts with a hash (#) and lives inside double braces. Think of them as tiny macros that the parser expands before the final HTML is spit out. The simplest example is the #if function:
{{#if:{{{title|}}}|{{{title}}}|No title provided}}Here the function checks whether the title parameter exists, and then either bold‑faces it or displays an italic placeholder. The pattern may look trivial, but once you start nesting #if, #ifeq, #switch, and friends, a template can make decisions that previously required PHP extensions.
Conditional Logic Gone Wild
MediaWiki ships with a suite of conditionals that, together, form a rudimentary programming language. Some of the most useful are:
- #if – existence test.
- #ifeq – strict equality.
- #iferror – catches parsing errors.
- #switch – multi‑branch selector.
- #expr – arithmetic and logical expressions.
Take #switch for a moment. It lets you map a single value onto many possible outputs without a cascade of #ifeq’s:
{{#switch:{{{status}}}
|approved = ✓ Approved
|rejected = ✗ Rejected
|pending = … Pending
|{{{status}}}
}}Notice the final line? It acts as a fallback, echoing whatever value slipped through if none of the explicit cases match. That tiny safety net often saves you from an ugly “unknown” label on live pages.
Math, Dates, and the #expr Function
If you ever needed to add two numbers together inside a template, you probably reached for #expr. It evaluates simple arithmetic, logical operators, and even some built‑in functions like int and formatdate. For example, a template that calculates a project’s remaining days might look like this:
{{#expr: ( {{#time:U}} - {{#:U|{{{deadline}}}}} ) / 86400 }}That snippet takes the current Unix timestamp (#time:U), subtracts the deadline’s timestamp, and divides by the number of seconds in a day. The result is a decimal; you could wrap it in #round if you only wanted whole days.
Iterating with #foreach
One limitation of core parser functions is the lack of true loops. Enter #foreach, introduced in MediaWiki 1.35. It iterates over a pipe‑separated list, letting you replicate a block of markup for each item. Here’s a quick example that builds a simple navigation menu:
{{#foreach:
|item1
|item2
|item3
|{{{item|ucfirst}}}
}}The {{{item}}} placeholder is automatically set to each list element. The ucfirst pipe (a small “magic word” you’ll find on MediaWiki’s documentation page) capitalises the first letter. A neat trick is to append a separator, like a comma, after each iteration and then strip the trailing one with #replace—a bit hacky, but it works.
#vardefine and #vardefineecho: Storing State
When your template starts juggling several intermediate values, you’ll quickly appreciate the variable functions. #vardefine assigns a value to a temporary variable that lives only for the duration of the page parse, while #vardefineecho does the same but also outputs the result immediately.
{{#vardefine:total|{{#expr: {{#vardefine:sum|0}} + {{#expr: {{{price}}} {{{qty}}} }}} }}Okay, that line looks gnarly, but the idea is simple: you initialise sum at zero, then add the product of price and quantity each time you process a line item. The final total variable can be echoed elsewhere.
When Lua Joins the Party
For truly advanced templating, many wikis have switched to Scribunto, the Lua module system. You can still invoke core parser functions from Lua, but the real power lies in the #invoke parser function, which runs a Lua script and returns its output. A typical pattern looks like this:
{{#invoke:MyModule|renderTable|{{{data}}}}}The corresponding Lua file (Module:MyModule) might use the mw.html library to build a table row‑by‑row, handling edge cases that would be a nightmare in pure wikitext. Yet the beauty is that you can still sprinkle regular parser functions inside the returned markup, letting the old and new co‑exist.
Practical Example: A Dynamic Infobox
Suppose you maintain an infobox for fictional characters. You want the box to display a “Birthplace” field only if the data exists, colour‑code the “Alignment” field, and compute the age on the fly. Here’s a compact template that showcases a handful of parser tricks.
{{Infobox character
| name = {{#if:{{{name|}}}|{{{name}}}|Unnamed}}
| image = {{{image|}}}
| alignment = {{#switch:{{{alignment|neutral}}}
|good = Good
|evil = Evil
|neutral = Neutral
|{{{alignment}}}
}}
| birthplace = {{#if:{{{birthplace|}}}|{{{birthplace}}}|}}
| age = {{#expr: floor( ( {{#time:U}} - {{#time:U|{{{birthdate|}}}}} ) / 31556952 ) }}
}}Notice the #if on birthplace. If the parameter is empty the whole line collapses, leaving no stray label. The #expr line divides the seconds‑difference by the average seconds per year, then rounds down, giving a clean integer age. All of that lives inside a single template file, no Lua required.
Debugging Parser Functions
It’s easy to get lost in a sea of nested #ifs. MediaWiki offers a handy {{#ifeq:}}ParserFunctions skin option, but many editors just sprinkle {{#show: calls to dump variable contents:
{{#show:{{{debug|}}}|debug}}When you pass a list of variables through #show, the output appears in a plain‑text block, making it quick to spot where a variable went missing. Remember to strip the debug line before publishing; it’s a classic human slip‑up that actually signals a thoughtful author.
Performance Considerations
Parser functions are cheap compared to full‑blown PHP extensions, but they’re not free. A template that loops over a long list with #foreach and repeatedly calls #expr can start to bite page load times. Some wikis mitigate this by caching intermediary results using #save and #load (features of the ParserFunctions extension when paired with the Cache extension). The idea is simple: compute once, reuse many times.
Common Pitfalls
- Forgotten closing braces – A stray “}}” can break the whole page, and the error message is often cryptic.
- Parameter name collisions – If two nested templates use the same parameter name, the inner one silently overwrites the outer.
- String vs. number – #expr treats everything as a string unless you coerce it with
intorfloat. - Whitespace quirks – Some functions trim spaces, others don’t; testing with invisible characters (like a non‑breaking space) can reveal hidden bugs.
Wrapping Up the Toolkit
Parser functions might feel like a relic from the early days of MediaWiki, yet they remain a cornerstone for advanced templating. Whether you’re building a compact infobox, a dynamic list of upcoming events, or a sophisticated age calculator, the suite of #if, #switch, #expr, #foreach, and variable helpers lets you squeeze logic out of pure wikitext. And when the limits of wikitext start to fray, a quick jump to Lua via #invoke extends the playground without abandoning the familiar syntax.
In practice, the best templates are a blend of clarity and cleverness – a dash of conditional branching, a pinch of arithmetic, and a sprinkling of loops for repeatable sections. Keep an eye on readability; a fellow editor will thank you when they can trace a #vardefine chain without pulling their hair out. And if you ever find yourself buried in a wall of nested #ifs, step back, maybe break the logic into a Lua module, and let the parser functions handle the glue that ties it all together.