Table of Contents
ParserFunctions Plugin
Compatible with DokuWiki
- 2024-02-06 "Kaos" yes
- 2023-04-04 "Jack Jackrum" yes
- 2022-07-31 "Igor" unknown
- 2020-07-29 "Hogfather" unknown
Description
Provides additional parser functions for DokuWiki inspired by the MediaWiki ParserFunctions Extension.
For now, just #if
, #ifeq
and #switch
functions are available, but it works very well and is a perfect companion for Templater and WST plugins (tested).
Installation
Please refer to Extension Manager for additional info on how to search and install extensions in DokuWiki. Refer to Plugins on how to install plugins manually.
Syntax
Basic syntax:
{{#functionname: argument 1 | argument 2 | argument 3 ... #}}
Please, note that:
- This plugin starts with
{{#
and ends with#}}
. MediaWiki ends with}}
, don't forget the difference! - White spaces at the beginning and end of the arguments are ignored. The middle ones are ok. To include white spaces at the beginning and/or end, enclose the argument between double quotes:
" string "
- To pass double quotes to the argument, add them inside double quotes:
"This is "phrase" with quotes."
- Functions can not be nested!
Escape Sequences
These characters:
- raw equals
=
- vertical bar (a.k.a. pipe)
|
- number sign (a.k.a. sharp, hash or pound sign)
#
- keys
{
and}
Are special characters for most of the functions. The raw equal =
can be used outside #switch
whithout need of any escape sequence. So you can use it in #if
or #ifeq
. But inside a #switch
, it need to be escaped. However, |
and #
need to be escaped in all the functions if you wish to add them to your string value or even a case. Here is how:
character | sequence |
---|---|
= | = |
| | | |
# | # |
{ | { |
} | } |
New escapes are easy to be added. In lib/plugins/parserfunctions/syntax.php
, search for function _escape($data)
and add escapes to the $escapes
array. You can refer to HTML Entity List. But replace any #
by #
.
Alternatively, talk to me and ask me to include the characters you need to escape.
#if
This function evaluates a test string and determines whether or not it is empty. A test string containing only white space is considered to be empty.
{{#if: test string | value if test string is not empty | value if test string is empty (or only white space) #}}
{{#if: first parameter | second parameter | third parameter #}}
This function first tests whether the first parameter is not empty. If the first parameter is not empty, the function displays the second argument. If the first parameter is empty or contains only whitespace characters (spaces, newlines, etc.) it displays the third argument.
It can be written in many ways: with or without spaces, line breaks, etc.
{{#if: | yes | no#}} → no {{#if: string | yes | no#}} → yes {{#if: | yes | no#}} → no {{#if: | yes | no#}} → no
The test string is always interpreted as pure text, so mathematical expressions are not evaluated (see #ifexpr
1) for that):
{{#if: 1==2 | yes | no #}} → yes {{#if: 0 | yes | no #}} → yes
The last parameter (false) may be omitted. It's usefull when user wants the result to be null if the test string is empty:
{{#if: foo | yes #}} → yes {{#if: | yes #}} → {{#if: foo | | no#}} →
If you are using Templater or WST plugins, you can also use a parameter as the test string in your #if
statement. Templater uses @parameter@
and WST adopts {{{parameter}}}
.
{{#if:{{{1}}}|You entered text in variable 1|There is no text in variable 1#}} {{#if:@1@|You entered text in variable 1|There is no text in variable 1#}}
To return the same text as the one given in the parameter just repete the string in the second field. You can use the third field as a “default” parameter or leave it blank to hide it.
{{#if: {{{1}}} | {{{1}}} | #}} → use {{{1}}} or hide if blank {{#if: @1@ | @1@ | default value #}} → use @1@ or "default value" if blank
#ifeq
This parser function compares two input strings, determines whether they are identical, and returns one of two strings based on the result. If more comparisons and output strings are required, consider using #switch
.
{{#ifeq: string 1 | string 2 | value if identical | value if different #}}
If both strings are valid numerical values, the strings are compared numerically:
{{#ifeq: 01 | 1 | equal | not equal#}} → equal {{#ifeq: 0 | -0 | equal | not equal#}} → equal {{#ifeq: 1e3 | 1000 | equal | not equal#}} → equal {{#ifeq: {{#expr:10^3#}} | 1000 | equal | not equal#}} → DOUBLE BUG
BUG 1: function #expr
was not implemented yet.
BUG 2: functions can not be nested yet.
Otherwise, the comparison is made as text; this comparison is case-sensitive:
{{#ifeq: foo | bar | equal | not equal#}} → not equal {{#ifeq: foo | Foo | equal | not equal#}} → not equal {{#ifeq: "01" | "1" | equal | not equal#}} → not equal [^1] {{#ifeq: 10^3 | 1000 | equal | not equal#}} → not equal [^2]
[^1]
: compare to similar example above, without the quotes.
[^2]
: compare to similar example above, with #expr
returning a valid number first.
There is no convention for the order, but it is simpler to read if the parameter goes first. For example, in a WST template, whose parameters are enclosed by {{{params}}}
:
This {{#ifeq: {{{1}}} | short | 20 | 40 #}} is equal to this {{#ifeq: short | {{{1}}} | 20 | 40 #}}, order does not matter!
#switch
This function compares one input value against several test cases, returning an associated string if a match is found.
{{#switch: comparison string | case = result | case = result | ... | case = result | default result #}}
Examples:
{{#switch: baz | foo = Foo | baz = Baz | Bar #}} → Baz {{#switch: foo | foo = Foo | baz = Baz | Bar #}} → Foo {{#switch: zzz | foo = Foo | baz = Baz | Bar #}} → Bar
Default
The default result
is returned if no case
string matches the comparison string
:
{{#switch: test | foo = Foo | baz = Baz | Bar #}} → Bar
In this syntax, the default result must be the last parameter and must not contain a raw equals sign (an equals sign without {{}}
). If it does, it will be treated as a case comparison, and no text will display if no cases match. This is because the default value has not been defined (is empty). If a case matches however, its associated string will be returned.
{{#switch: test | Bar | foo = Foo | baz = Baz #}} → {{#switch: test | foo = Foo | baz = Baz | B=ar #}} → {{#switch: test | test = Foo | baz = Baz | B=ar #}} → Foo
Unlike MediaWiki, the default value cannot be explicitly declared as a case string. You cannot use #default = value
.
Additionally, the default result can be omitted if you do not wish to return anything if the test parameter value does not match any of the cases. All of these situations are the same:
{{#switch: zoo | foo = Foo | bar = Bar #}} → {{#switch: zoo | foo = Foo | bar = Bar | #}} →
Grouping results
It is not possible to have 'fall through' values, where several case
strings return the same result
string. This minimizes duplication. But this is not implemented in this plugin yet.
{{#switch: comparison string | case1 = result1 | case2 | case3 | case4 = result234 | case5 = result5 | case6 | case7 = result67 | #default = default result #}}
Here cases 2, 3 and 4 should all return result234
; cases 6 and 7 both should return result67
. But they will not, because 'fall through' was not implemented yet. The “#default =
” in the last parameter may must be omitted in the above case.
Use with template parameters
This plugin is compatible with Templater and WST. This is because ParserFunctions are rendered after them.
WST template → {{#switch: {{{1}}} | foo = Foo | baz = Baz | Bar #}} Templater template → {{#switch: @1@ | foo = Foo | baz = Baz | Bar #}}
In the above case, if {{{1}}}
or @1@
equals foo
, the function will return Foo
. If it equals baz
, the function will return Baz
. If the parameter is empty or does not exist, the function will return Bar
.
Works with named case strings of course: {{{parameter}}}
or @parameter@
. Function evaluates the parameter's value, not the parameter itself. If parameter is empty, it will return the default value. If there is no default value, it is null
(= ""
).
Comparison behavior
As with #ifeq
, the comparison is made numerically if both the comparison string and the case string being tested are numeric.
Raw equal signs
Remember that raw equals signs =
can be escaped by =
.
Replacing #ifeq
#switch
can be used to reduce expansion depth, but can not be nested (as any other function): function inside function, #switch
inside another #switch
or an #if
inside a #switch
etc, are not possible.
Development
The source code of the plugin is available at GitHub: https://github.com/nerun/dokuwiki-plugin-parserfunctions.
Changelog
- Date and copyright. (2024-06-21 21:19)
- Added escapes for { and }, addressing issue #1. (2024-06-21 21:15)
- Adjustments to dokuwiki standards dokuwiki.org/devel:badextensions (2024-05-19 16:21)
- Added escape sequences for "#", "|" and "=". (2023-12-11 15:54)
- Implemented #switch function (2023-12-11 03:36)
- Implemented #ifeq function (2023-12-10 19:50)
- Added manager.dat to giattributes and gitignore (2023-12-10 17:03)
- plugin.info version date (2023-12-10 16:56)
Known Bugs and Issues
- none for now.
ToDo/Wish List
- Allow nested functions.
#switch
: add “fall through”values
, where severalcase strings
return the sameresult string
.
FAQ
[discussions should ideally be deleted and turned into FAQ entries along the way]