Mastering MediaWiki Parser Functions for Advanced Templating
The practical ParserFunctions reference: conditionals, #switch, #expr, string functions and URL helpers, with real syntax and usage notes.
ParserFunctions is the extension that turns templates from static markup into logic. This is the working reference: the functions that matter most, real syntax, and the usage notes that templates eventually need. It complements the templating guide on this blog — here we go function by function.
Conditionals
{{#if: {{{param|}}} | value-when-nonempty | value-when-empty }}
{{#ifeq: a | b | equal | not-equal }}
{{#ifexpr: 2 + 2 = 4 | yes | no }}
{{#iferror: {{#expr: 1/0 }} | broken | fine }}
{{#ifexist: Page name | exists | missing }}
#iftests non-empty (note: '0' counts as empty — a classic bug; use#ifeqfor numeric zero checks)#ifeqcompares strings or numbers; the workhorse for value dispatch#ifexistqueries page existence — it costs a database lookup per use, so keep it out of hot templates or cache the result
Switch — the readable dispatcher
{{#switch: {{{status|}}}
| draft = {{draft-banner}}
| review = {{review-banner}}
| published = {{live-banner}}
| #default = {{unknown-status}}
}}
#switch falls through values listed on the same line separated by |; keep one case per line for readability. It beats nested #ifeq in both speed and maintainability — nested conditionals are the template anti-pattern to refactor.
Expressions
{{#expr: 2 * (3 + 4) }} → 14
{{#expr: 10 / 4 round 2 }} → 2.5
{{#expr: {{PAGESINCATEGORY:Books}} / 10 round 0 }}
#expr supports arithmetic, comparisons, boolean AND/OR/NOT and the round operator. Performance: #expr is cheap; the expensive part is usually the inputs (page-count magic words) — compute once in a template variable or a Lua module for repeated use. For output, wrap in #iferror or use formatnum|R= to control number formatting.
String functions
{{#len: Hello }} → 5
{{#sub: Hello world | 6 | 5 }} → world
{{#pos: Hello world | world }} → 6
{{#replace: a-b-c | - | _ }} → a_b_c
{{#padleft: 42 | 5 | 0 }} → 00042
{{#explode: a,b,c | , | 1 }} → b
{{#titleparts: X/Y/Z | 1 | 2 }} → Y
String functions are linear-time operations; long strings and #explode loops on big data are where templates get slow. Heavy text processing belongs in Lua (Scribunto), which handles Unicode properly via mw.ustring.
Time and language
{{#time: Y-m-d }} → 2026-08-15 (server date)
{{#timel: Y-m-d }} → same, in user's timezone
{{#language: de }} → Deutsch
{{#formatnum: 1234567 }} → 1,234,567
#time formats PHP date() syntax in the wiki's timezone; #timel follows the user's preference. Use #formatnum for user-facing numbers and formatnum|R= to parse formatted input back.
URL helpers
{{#urlencode: a b/c }} → a+b%2Fc (or %20 with QUERY mode)
{{#anchorencode: Section 1 }} → Section_1
{{fullurl: Page|action=edit}}
{{canonicalurl: Page}}
#urlencode (mode QUERY or PATH) escapes fragments for links and API calls; fullurl is the standard way to build links programmatically (the MediaWiki URL magic words are technically core, not ParserFunctions, but they belong in every URL-building toolkit).
Limits and good practice
- ParserFunctions add to the expansion cost: MediaWiki aborts templates past the expansion depth/time limits — deep conditional nesting is the usual trigger
- For logic beyond functions (loops, tables, state),
#invokeLua modules instead; they are faster and sandboxed (see the Scribunto reference) - Test with the extension docs alongside — the quirks (zero-is-empty, whitespace handling, string positions) are documented there, and the parser functions cheat sheet on Wikipedia rounds out the reference