MediaWiki Parser Functions — #if, #switch, #expr, #time, and Conditional Templates
In this tutorial, you will learn about MediaWiki Parser Functions. We cover key concepts, practical examples, and best practices to help you master this topic.
Parser functions in MediaWiki are built-in programming constructs that add conditional logic, arithmetic, date formatting, and string manipulation to wikitext — transforming templates from static snippets into dynamic, intelligent components like those used across Wikipedia's infoboxes and navigation systems.
What You'll Learn
- Using
{{#if:}}for conditional content display - Using
{{#switch:}}for multi-case selection - Performing calculations with
{{#expr:}} - Formatting dates with
{{#time:}} - Checking page existence with
{{#ifexist:}} - Building a complete dynamic template
Why It Matters
Without parser functions, a template always shows the same content. With them, a template can decide what to display based on input. A "User Status" template can show "Online" in green or "Offline" in red. An "Age Calculator" template can compute years from a birth date. A "Navigation Box" template can show or hide sections based on whether the target page exists. Parser functions turn wikitext into a basic programming language.
Real-World Use
A DodaTech documentation wiki has a "Version Info" template that accepts a version number and displays release date, LTS status, and support end date. It uses #if to check whether the version is older than 3.0 (showing a "Legacy" warning), #switch to map version numbers to release dates, #expr to calculate years since release, and #time to format dates consistently.
Learning Path
flowchart LR A["12: Image & Media"] --> B["13: Transclusion"] B --> C["14: Parser Functions"] C:::current D["15: Subpages"] E["16: Redirects"] F["17: Categories"] C --> D --> E --> F classDef current fill#38bdf8,color#0f172a,stroke-width:2px
What Are Parser Functions?
Parser functions look like templates but are built into MediaWiki. They start with # and use a colon instead of a pipe for the first separator:
{{#if: condition | then-value | else-value }}
The colon separates the function name from its first argument. Pipes separate additional arguments.
#if — Conditional Display
{{#if:}} checks whether a string is non-empty and displays different content accordingly.
{{#if: {{{1|}}}
| The parameter was provided.
| No parameter was provided.
}}
If {{{1}}} has a value, the first line after the pipe is shown. If it is empty or not provided, the second line is shown.
{{#if: {{{online|}}}
| <span style="color:green;">Online</span>
| <span style="color:red;">Offline</span>
}}
A page using this template:
{{UserStatus|online=yes}}
Displays "Online" in green. Without the parameter, it shows "Offline" in red.
Important: #if checks if the string is non-empty. A value of 0 or false is still a non-empty string, so #if considers it true. For boolean logic, use #ifeq or #iferror.
#ifeq — String Equality
{{#ifeq: {{{format|}}} | pdf
| Show PDF download link
| Show HTML version
}}
This checks if the format parameter equals "pdf" exactly. Use this for template parameters that accept specific string values.
#ifexpr — Mathematical Condition
{{#ifexpr: {{PAGESIZE:Main Page}} > 5000
| Main Page is over 5KB
| Main Page is under 5KB
}}
This evaluates a mathematical expression and shows one of two values based on whether the result is non-zero. Use comparison operators: >, <, >=, <=, =, !=.
#iferror — Error Checking
{{#iferror: {{#expr: 1/0}} | Division by zero! | {{#expr: 1/0}} }}
This checks whether the first argument produces a MediaWiki error. If it does, the second argument is shown. If not, the third argument is shown.
#ifexist — Page Existence
{{#ifexist: Template:Infobox
| Template:Infobox exists
| Template:Infobox does not exist
}}
This checks whether a page exists on the wiki. It is useful for navigation templates that should only link to pages that have been created.
#switch — Multi-Case Selection
{{#switch:}} is like an if-else chain or a switch/case statement in programming.
{{#switch: {{{severity|info}}}
| error = <span style="color:red;">Error</span>
| warning = <span style="color:orange;">Warning</span>
| info = <span style="color:blue;">Info</span>
| #default = <span style="color:gray;">Unknown</span>
}}
If severity is "error", it shows "Error" in red. If "warning", it shows orange. If "info" or anything not listed, it shows the default.
The #default case catches all unspecified values. Without a default, unmatched values produce nothing.
Switch with Multiple Values per Case
{{#switch: {{{os|}}}
| windows | win | w = Windows
| mac | macos | darwin = macOS
| linux | unix = Linux
| #default = Other
}}
Multiple values on the same line (separated by pipes) all map to the same result. The template accepts "Windows", "win", or "w" and returns "Windows".
#expr — Mathematical Expressions
{{#expr:}} evaluates arithmetic expressions and returns the result.
{{#expr: 2 + 2 }} Renders: 4
{{#expr: 10 / 3 }} Renders: 3.3333333333333
{{#expr: 10 / 3 round 2 }} Renders: 3.33
{{#expr: 2 ^ 10 }} Renders: 1024
{{#expr: (5 + 3) * 2 }} Renders: 16
{{#expr: pi * 5 ^ 2 }} Renders: 78.539816339745
Supported operators:
- Arithmetic:
+,-,*,/,^(power) - Comparison:
=,!=,<,>,<=,>= - Logical:
and,or,not - Functions:
abs,ceil,floor,trunc,round,ln,log,sin,cos,tan,pi
Practical Example: File Size Display
{{#expr: {{PAGESIZE:{{{page|Main Page}}}}}
/ 1024 round 1 }} KB
This displays the size of any page in kilobytes, rounded to one decimal place. The PAGESIZE magic word returns the content length in bytes.
#time — Date Formatting
{{#time:}} formats dates and timestamps.
{{#time: Y-m-d }} Renders: 2026-06-28
{{#time: l, F j, Y }} Renders: Sunday, June 28, 2026
{{#time: H:i:s }} Renders: 14:30:00
{{#time: r }} Renders: Sun, 28 Jun 2026 14:30:00 +0000
{{#time: Y }} Renders: 2026
Format codes (same as PHP date()):
Y— 4-digit yeary— 2-digit yearF— Full month name (January)M— 3-letter month (Jan)m— 2-digit monthd— 2-digit day with leading zeroj— Day without leading zerol— Day of week (Sunday)D— 3-letter day (Sun)H— 24-hour hourh— 12-hour houri— Minutess— Secondsr— RFC 2822 date
Custom Timestamps
{{#time: Y-m-d | 2026-01-15 }} Renders: 2026-01-15
{{#time: F j, Y | {{REVISIONTIMESTAMP}} }} Renders: January 28, 2026
The second parameter to #time is a timestamp. Without it, the current time is used. You can pass any valid date string.
Practical Example: Age Calculator
{{#expr:
{{#time: Y}} - {{{year|2020}}}
- ({{#time: md}} < {{{month|01}}}{{{day|01}}} ? 1 : 0)
}} years old
This template calculates age from a birth year, month, and day. It subtracts one year if the current date is before the birthday this year.
#tag — XML Tags
{{#tag:}} generates XML-style tags programmatically.
{{#tag:syntaxhighlight|
function hello() {
console.log("Hello, world!");
}
|lang=javascript
}}
This is how templates can generate <syntaxhighlight> blocks with dynamic content. The first parameter is the tag name, the second is the content, and additional parameters become attributes.
Putting It Together: A Dynamic Infobox
Let's build a "Product" infobox that uses all the parser functions we learned:
<includeonly>{| class="wikitable" style="float:right;width:300px;"
|+ {{{name|Product Name}}}
|-
{{#if:{{{version|}}}|
! Version
| {{{version}}}
|-
}}
{{#if:{{{release|}}}|
! Release Date
| {{#time: F j, Y | {{{release}}} }}
|-
}}
{{#if:{{{size|}}}|
! Size
| {{#expr: {{{size}}} / 1024 / 1024 round 1 }} MB
|-
}}
! Status
| {{#switch: {{{status|stable}}}
| stable = <span style="color:green;">Stable</span>
| beta = <span style="color:orange;">Beta</span>
| alpha = <span style="color:red;">Alpha</span>
| deprecated = <span style="color:gray;">Deprecated</span>
| #default = Unknown
}}
|-
{{#ifexist: Template:Product_{{ROOTPAGENAME}}_Nav |
! Navigation
| {{Product_{{ROOTPAGENAME}}_Nav}}
|-
}}
|}</includeonly>
<noinclude>
== Usage ==
{{Product
|name=DodaSync
|version=2.1
|release=2026-06-01
|size=15728640
|status=stable
}}
</noinclude>
This template uses:
#ifto hide rows when parameters are empty#timeto format the release date#exprto convert bytes to megabytes#switchto color the status text#ifexistto conditionally include a navigation template
What You Learned
#ifshows content based on whether a string is non-empty#ifeqcompares two strings for equality#switchselects content from multiple cases#exprevaluates mathematical expressions#timeformats dates with PHP-style format codes#ifexistchecks whether a page exists- Parser functions can be nested for complex logic
In the next lesson, you'll learn about subpages — a way to create parent-child page hierarchies for organized content.
Common Mistakes
| Mistake | Why It Happens | How to Fix |
|---------|---------------|------------|
| #if treats "0" as empty | #if checks for non-empty strings, and "0" is technically non-empty. However, an empty string is falsy. If you need to check for a zero number, use #ifeq. | Use {{#ifeq: {{{param|}}} | 0 | ... }} for exact comparison. |
| #expr returns errors for invalid expressions | The expression contains unsupported operators or syntax | Check for valid operators. Use floor, ceil, or round to handle division results. Wrap in #iferror to handle gracefully. |
| #time shows the wrong date | Timezone not configured | Set $wgLocaltimezone = 'UTC' or your timezone in LocalSettings.php. #time uses the server timezone. |
| #switch does not match when it should | Leading or trailing whitespace in the value | Trim whitespace from parameters: {{#switch: {{{param|}}} }}. Spaces in parameter values can cause mismatches. |
| Nested parser functions are hard to read | Complex logic in one line | Break into multiple template calls or use intermediate templates for sub-expressions. Deep nesting is confusing and error-prone. |
| #ifexist slows down the wiki | Checking many pages per render | Use #ifexist sparingly. Each call checks the database. On a page with 50 #ifexist calls, rendering can be noticeably slow. |
| Parser function output shows raw code | Syntax error in the function call | Check colons vs pipes. {{#if:condition|then|else}} is correct. A common mistake is {{#if|condition|then|else}} with pipe instead of colon. |
Practice Questions
- Write a parser function expression that displays "Over 100 KB" if the page size exceeds 102400 bytes, and "Under 100 KB" otherwise.
- Create a template called "SeasonalGreeting" that uses
#switchto display a different greeting based on the current month: "Happy New Year" for January, "Spring is here" for March-May, "Summer vibes" for June-August, "Autumn leaves" for September-November, and "Happy Holidays" for December. - How would you calculate and display a person's age given their birth year, month, and day as template parameters?
- Challenge: Build a "System Requirements" template that accepts three parameters:
os,ram_mb, anddisk_mb. The template should use#switchto display "Windows", "macOS", or "Linux" based on the OS abbreviation. Use#exprto convert RAM from megabytes to gigabytes (rounded to 1 decimal). Use#ifto hide any row where the parameter is empty. Add a#ifexistcheck for a "System Requirements Notes" page and append a link if it exists.
FAQ
Mini Project
Goal: Create a "System Info" template that displays dynamic server information.
- Create
Template:SystemInfowith parameters:hostname,os,uptime_days,cpu_usage,ram_total_gb,ram_used_gb,status - Use
#ifto hide rows where parameters are empty - Use
#exprto calculate RAM usage percentage:(ram_used_gb / ram_total_gb) * 100 round 1 - Use
#switchto color the status: online=green, maintenance=yellow, offline=red - Use
#timeto display the current date at the bottom: "Report generated on June 28, 2026" - Use
#ifexprto show a warning when CPU usage exceeds 80% - Create a test page that uses the template with real-looking data
- Add
#ifexistto check for a "Server:{{hostname}}" page and link to it if it exists
What's Next
Parser functions give your templates intelligence. Now let's organize your wiki content with subpages — a hierarchy for related pages.
Continue to Lesson 15: Subpages — learn how subpages create parent-child relationships and automatic breadcrumb navigation.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro