YK: Chapter 12: Extended MediaWiki syntax
12 Extended MediaWiki syntax
There’s a variety of other syntax, available through extensions, that can be used for specific purposes: displaying specialized content, handling logic, and displaying page elements such as tabs and footnotes. We’ll get to some of it in this chapter.
ParserFunctions
The single most indispensable MediaWiki extension, and likely the most popular, is the ParserFunctions extension. As you may be able to guess from its name, ParserFunctions defines a collection of parser functions (see here for an explanation of those). The functions it defines are useful in a variety of circumstances. Since 2010, ParserFunctions has included all the code for what used to be a separate extension, StringFunctions. The original ParserFunctions function are all programmatic in nature: there’s #if, the most important of them, which does conditional display, #expr, which evaluates mathematical expressions, and others along similar lines; the full listing is below. The functions that came from StringFunctions all do typical string-manipulation actions, like getting substrings, and replacing certain substrings with others.
In practice, almost all of the usages of functions defined by ParserFunctions are in templates, because that’s the one case where you don’t know in advance what all the values passed in will be. That’s why most of the examples later on for ParserFunctions functions take place within the context of a template, with passed-in parameters.
ParserFunctions comes bundled in with the downloadable version of MediaWiki. But why, given that it’s so popular, isn’t its functionality directly a part of core MediaWiki? That’s because ParserFunctions is a bit of a hack. Functions like #if, for all their helpfulness, can be cumbersome to use, and you only need to look at the code for some of the templates in Wikipedia to see how such functions can quickly turn wikitext into an unreadable mess of curly braces. Here’s a small example, from the English Wikipedia’s “Infobox settlement” template:
{{#ifeq: | para | : {{#if: | {{{p1}}} {{#if: |, {{{p2}}} {{#if: |, {{{p3}}} {{#if: |, {{{p4}}} {{#if: |,
It goes on like that for a while.
Almost as soon as ParserFunctions was created, discussions began about replacing it with true scripting functionality, including "if-then" statements, "for" loops, and the like, which would be both more powerful and more elegant than the current approach. This finally came about in 2013 with the Scribunto extension, which allows for creating “modules”, written in the scripting language Lua, which can include sophisticated logic and text processing:
https://www.mediawiki.org/wiki/Extension:Scribunto
Scribunto is intended to be a powerful framework, by the way: though its default scripting language will be Lua, it’s designed to allow other languages as well, such as JavaScript (server-side, not client-side).
Nevertheless, ParserFunctions is still in widespread use, even on Wikipedia. Below is the listing of the original functions it defines, along with a description of each.
- expr displays the result of a mathematical or logical expression.
Example: 5
- if displays different strings depending on whether some value is blank.
Example: No height entered.
- ifeq displays different strings depending on whether two values are equal.
- iferror displays different strings depending on whether a call to another such function returned an error.
- ifexpr displays different strings depending on whether a mathematical expression is correct.
- ifexist displays different strings depending on whether a given page exists.
- rel2abs displays a page name, based on a directory-like view of subpages.
- switch displays different strings depending on some specific value (there can be multiple options).
Example: It’s some other season!
- time displays a specific time, in a specified format.
- timel displays the current local time, in a specified format.
- titleparts displays one or more parts of a page name, based on splitting up the page by slashes.
Example: C/D (returns “C/D” call returns 2 segments, starting at segment #3)
And here are the ParserFunctions functions that came from StringFunctions:
- len shows the length of a given string.
Example: Expression error: Unrecognized punctuation character "[".
- pos finds the numerical character position of one string within another.
- rpos similar, but finds the last occurrence of a string.
- sub shows the substring of a string, given a start and end location.
- pad pads out a string to a certain length, using a character or longer string as padding.
- replace shows a string that has had a substring replaced with another string.
- explode shows a substring, based on splitting up a string by a delimiter.
Example: The third name in your list is {{#explode:|,|3}}.
urldecode URL-decodes a string, e.g. turning ’%20’ into ’ ’, etc.
urlencode URL-encodes a string; sometimes useful for creating links.
Note the lack of a “#” at the beginning of both urldecode and urlencode.
You can read more about ParserFunctions, including many additional examples, here:
https://www.mediawiki.org/wiki/Extension:ParserFunctions
Displaying code
You may want to display source code in some programming or markup language on a wiki page, if it’s, say, part of a software-related wiki. The awkwardly-named SyntaxHighlight GeSHi is the recommended extension for doing that. It uses the third-party GeSHi library, whose name itself stands for “Generic Syntax Highlighter”. The extension defines the tagInvalid language.
You need to specify a language like this: <source lang="html4strict">...</source>
Supported languages for syntax highlighting:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, arm, asm, asp, asymptote, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcl, dcpu16, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, nagios, netrexx, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, octave, oobas, oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, pys60, python, q, qbasic, rails, rebol, reg, rexx, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, spark, sparql, sql, stonescript, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vedit, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic
, which takes in the parameter lang=, which can hold any of over 100 language names, and can then display any set of code. Here’s one example call: <syntaxhighlight lang="java"> System.out.println( "Bonjour, monde!" );
And here is the resulting output:
[]
Invalid language.
You need to specify a language like this: <source lang="html4strict">...</source>
Supported languages for syntax highlighting:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, arm, asm, asp, asymptote, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcl, dcpu16, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, nagios, netrexx, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, octave, oobas, oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, pys60, python, q, qbasic, rails, rebol, reg, rexx, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, spark, sparql, sql, stonescript, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vedit, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic
can take in some other parameters, which modify the display; these are only rarely used, but here are some of them: line adds a line number at the beginning of each line. start= if line is used, sets the line number for the first line (by default it’s 1). highlight= specifies a line to highlight. enclose= specifies the HTML tag used to enclose the entire text. By default it’s "pre", but it can also be "div" or "none". Using "div" allows for line wrapping, which is helpful when there are long lines of code. See the SyntaxHighlight GeSHi homepage for more information on how to download and use this extension, including the full set of languages allowed: https://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi Displaying math The Math extension lets you display mathematical formulas on the page in a nicely-formatted way, by placing them within the <math> tag. This functionality was formerly part of core MediaWiki, until it was spun off into an extension in version 1.18. You can see more information here: https://www.mediawiki.org/wiki/Extension:Math Cite The Cite extension should be well-known to anyone who has read Wikipedia it’s the extension that lets users create footnotes. It’s not used often outside of Wikipedia and other Wikimedia sites, but it can, and probably should, be used more often, because providing citations for facts is always a good idea. To add a footnote after a statement on a page, you can add something like the following afterward: <ref name="USA Today interview"> [http://usatoday.com/1234567.html Interview with a Screen Legend], Dana Douglas, ''USA Today'', January 1, 1980. Page retrieved February 2, 2014.</ref> The citation style is up to you, and you can use a template to set the formatting; that’s how it’s often done on Wikipedia, using templates like “cite news” and “cite web”. On Wikipedia, you could do, in place of the former, <ref name="USA Today interview">{{cite news |url=http://usatoday.com/1234567.html |title=Interview with a Screen Legend |first=Dana |last=Douglas |work=USA Today |date=January 1, 1980 |accessed=February 2, 2014}}</ref> This will guarantee a consistent display of citations. The “name=” attribute within the <ref> tag is optional it’s useful if you cite the same source more than once. If that happens, every additional citation can simply look like this: <ref name="USA Today interview" /> Finally, at the bottom of the page, you need the following tag to display the full set of footnotes: <references /> The English Wikipedia has a “{{Reflist}}” template that displays this tag, and applies some custom formatting around it. Header Tabs Header Tabs is a cool extension that lets you place tabs within a wiki page (separate from, and below, the editing-based tabs provided by the skin), thus letting you break up the content of what might otherwise be overly-long pages. It’s fairly limited: it can only create one set of tabs on a page, with no sub-tabs. Still, that by itself is enough to make pages a lot more readable in a variety of circumstances. To create a tab with Header Tabs, just print the tab name as a top-level section header, i.e. with one ’=’, like this: =Tab name= This takes advantage of the fact that top-level headers are usually unused; two equals signs (’==’) and higher are recommended for regular page headers in almost all cases. Here’s an example of the display of tabs, for a page about an athlete: [] This display would just require having lines like “=Biography=”, “=Statistics=”, etc. within the wikitext. Even if you have Header Tabs installed, such headers won’t automatically get turned into tabs unless you do one of two things. The first option is to place the tag <headertabs /> somewhere below the set of tabs for the page; wherever it goes marks the end of the contents of the last tab, and everything below the <headertabs /> will show up below the tabs structure. The other option is to designate one or more namespaces as automatically getting tabs, so that headers with a single equals sign around them will get turned into tabs, without the need for a <headertabs /> tag. You can do this by adding to the global variable $htAutomaticNamespaces, within LocalSettings.php. So to make tabs automatically show up for every page in the main namespace, you would add the following line, below the inclusion of Header Tabs: $htAutomaticNamespaces[] = NS_MAIN; (If you don’t know PHP, this line adds the value “NS_MAIN” to the array of values that $htAutomaticNamespaces already held.) This approach is certainly more convenient; its downside is that you can’t have a section of the page below the tabs area everything from the last tab name down to the end will become part of the last tab’s contents. (Although you can still manually insert a <headertabs /> tag in the right place to get around this problem.) In either case, you also need to have at least two such headers on a page for tabs to show up unless you add "$htRenderSingleTab = true;" to LocalSettings.php. Tabs are useful for a variety of purposes; though we’ve most often seen them in structured pages, defined by templates and editable with forms (using Semantic Forms Chapter 17). The structured, data-centric nature of such pages makes splitting them into tabs a very natural fit. In this case, it makes sense to have the set of tabs be the same for the page and for the form. There other customizations you can do, also within LocalSettings.php, to modify some of the other aspects of Header Tabs. By default, every click on a tab adds another page to the browser history, so that hitting the "back" button will bring you back to the previous tab you were on. You can disable this behavior, so that tabs won’t show up in the browser history, by adding the following: $htUseHistory = false; Every tab also gets an "edit" link that shows up on the right-hand side. You can remove this link by adding the following: $htEditTabLink= false; You can also change the display of the tabs, using the "$htStyle" global variable. The default display is also the nicest-looking one, but you can, for instance, switch to the default display that jQuery UI provides, by adding the following: $htStyle = 'jquery'; Header Tabs also provides a parser function, #switchtablink, that produces a link to a specific tab, from within either the page on which the tab is located or another page. It is called in the following format: {{#switchtablink:Tab name|Link text|Page name}} If the tab is on the same page as the link, only the first two parameters are needed; if it’s called from another page, the third parameter is needed as well. More information about Header Tabs can be found at: https://www.mediawiki.org/wiki/Extension:Header_Tabs