Contents
Welcome to Winter 2.0Edit
Winter was created in late 2005 to fill a need for simple scripting on MediaWiki pages. It has since grown to become a full-fledged language in its own right. Mostly reminiscent of PHP, it also has a bit of a LISP's recursive feel. Version 2.0 adds true array capability as well as many new functions, operations, and configuration settings.
This is the documentation for Winter v2.0+. The documentation for Winter v1.5 and below is also available.
Installation and ConfigurationEdit
InstallationEdit
- Place Winter.php in your wiki's the extensions directory.
- Add
require_once("extensions/Winter.php");
to the bottom of LocalSettings.php.
ConfigurationEdit
Winter has five options which may be set by defining variables in LocalSettings.php. These options must be set before the require_once call is made. The default settings are a bit forgiving; depending on your needs you may wish to modify them. This is especially true if your wiki is heavily used and/or faces risk of DoS attacks.
$wgWinterNamespacesEdit
Allows you to define in which namespaces Winter shall be enabled. Winter is enabled in all namespaces by default. See the list of namespaces to find out which
number corresponds to which namespace.
This example disables Winter on Talk and User_talk pages:
$wgWinterNamespaces = array( 2 => false, 3 => false);
$wgWinterMaxNestingEdit
Sets the maximum number of nesting levels allowed. Helps prevent stack overflows from runaway recursion. Default is 50.
$wgWinterMaxNesting = 50;
$wgWinterMaxOperationsEdit
Sets the maximum number of operations per script allowed. Prevents excessive program length. Note this is not the number of commands in the code, but rather the total amount of commands inside loops and used via shortcut syntaxes. Default is 10000.
$wgWinterMaxOperations = 10000;
$wgWinterMaxIterationsEdit
Set the maximum number of per-loop iterations allowed. Helps prevent infinite loops. Default is 1000.
$wgWinterMaxIterations = 1000;
$wgWinterNotAllowedEdit
Defines which functions are not allowed to be used. This applies to built-in functions, Winter function extensions, and also functions defined within the Winter code. No functions are blocked by default.
// Default $wgWinterNotAllowed = ""; // Example $wgWinterNotAllowed = "preg_match xml_xpath html_to_xml";
Extending Winter with custom PHP functionsEdit
Winter also allows for functions written in PHP to be defined via LocalSettings.php. These functions must be defined after requiring the Winter PHP file.
$wgWinter->addFunctionEdit
Use the method $wgWinter->addFunction to add a custom function definition.
$wgWinter->addFunction('WinterFunction','PHPFunction');
When WinterFunction is called within the Winter script, it will trigger PHP to call the PHP function named PHPFunction. PHPFunction will be passed an array beginning with the Winter function name followed by the parameter values.
$wgWinter->addVarEdit
Use the method $wgWinter->addVar to add a variable to the Winter script.
$wgWinter->addVar( 'varname' , 'value' ); $wgWinter->addVar( 'varname' , array() ); $wgWinter->addVar( array('X','Y') , 'value' );
Two-dimensional arrays may be created using the third syntax type.
Added in Winter 2.1.0
$wgWinter->showErrorEdit
$wgWinter->showError returns text formatted like other Winter error messages.
return $wgWinter->showError("There was a problem with a parameter");
Take care to ensure all data is properly formatted so that your script does not cause PHP errors. A Winter error message will appear in line with the rest of the text, as opposed to PHP error messages with end up at the top left (usually underneath the site logo) making the site look very broken.
ExampleEdit
$wgWinter->addFunction('WinterFunction','PHPFunction'); function PHPFunction($params) { if (count($params) == 3) { if ($params[1] == 5) { // show custom error message global $wgWinter; return $wgWinter->showError("First parameter in $params[0] can't be 5!"); } else { return "Function $params[0] has two parameters: $params[1] and $params[2]"; } } else { return false // will display general syntax error } }
Language SpecificationEdit
SyntaxEdit
Winter functions follow a similar syntax to MediaWiki templates, beginning with double braces {{ followed by the function name which always must start with a hash mark #. Valid characters for function names are alphanumeric characters, underscore _, dash, and dollar sign. The acceptable characters can be represented by this regular expression: [\wa-zA-Z0-9\_\-\$]
If there are any parameters they are separated by pipes. The function call ends with a closing double brace }}.
{{#command}} {{#command| param 1 | param 2 }} {{#command| param 1 | param 2 | ... | param n }}
Any parameter may include nested functions, however the function name may not have nested functions within its text. After execution, the text of the function call will be replaced with its return value.
{{#command | param 1 | {{#command2 | param 1 | param 2 }} }}
Like templates, white space surrounding the | character is ignored. Unlike templates, you may also use quotation marks (") to demarcate the beginning and ending of a string. This is useful when you would like to end or begin a parameter with whitespace. Only quotation marks at the beginning and end of a parameter string will have any effect on the string.
{{#command|param}} ---> 'param' {{#command| param }} ---> 'param' {{#command| " param " }} ---> ' param ' {{#command| " param }} ---> ' param' {{#command| par"am " }} ---> 'par"am '
Simple shortcut syntaxEdit
If all the parameters of a function are a single word without white space or nested functions, the following shortcut may be used:
{{#command one 2 three 4}} ---> {{#command|one|2|three|4}} {{#command {{#variable1}} two }} ---> invalid
Data TypesEdit
Alphanumeric stringEdit
Generally speaking, almost all data in Winter is alphanumeric or can be expressed alphanumerically. If a numeric value is expected, the string will be converted into a numeric value by if at all possible, just as in PHP. The first character in a string is at position 0.
BooleanEdit
Not a true data type. The following strings correspond to false:
- 0
- An empty string
All other values correspond to true.
ListEdit
Not a true data type, but rather an alphanumeric string which is a collection of substrings separated by | (pipe) characters. It is also the alphanumeric expression of an array.
ArrayEdit
Arrays are a compound data type consisting of one or more alphanumeric strings or arrays which have a an associated key by which the element is referenced. Arrays can have a maximum of 2 dimensions. Any arrays created having more than 2 dimensions (by copying a 2D array into another array for example) will have the additional dimensions 'flattened' or imploded recursively into a list inside the array.
When an array is used where a string is expected, it is flattened and returned as a list.
VariablesEdit
Variables are defined, retrieved and operated on using #var. Undefined variables referenced with #var will be created and set to empty string. Variable names are not case sensitive.
Returns the value of variable foo.
{{#var | foo }}
Performs an operation
{{#var | foo | operator | value }}
Sets the value and returns it
{{#var | foo | = | value }}
Sets the value and returns nothing
{{#var | foo | @= | value }}
Array data can also be accessed using #var.
{{#var | foo | x-index }} {{#var | foo | x-index | y-index }}
You may also use the new []= operator to assign values to array. Again you may use @ to suppress the return value.
{{#var | foo | [ x-index ]= | value }} {{#var | foo | [ x-index ][ y-index ]= | value }}
You may also use the deprecated #setvar to set variables and arrays.
{{#setvar | foo | value }} {{#setvar | foo | x-index | value }} {{#setvar | foo | x-index | y-index | value }}
ScopeEdit
Variables defined within function are local to the function. Variables defined outside of the function cannot be accessed directly inside the function; you must pass the value via function parameter.
Variable shortcut syntaxEdit
If a valid, yet unknown function call is encountered, it will be converted into a variable reference.
{{#foo}} converted to --> {{#var | foo }} {{#foo | @= | value }} converted to --> {{#var | foo | @= | value }} {{#foo @= value }} converted to --> {{#var | foo | @= | value }}
Variable names must meet the qualifications as a function name to use the shortcut syntax. For example:
{{#var | VarName | = | 1 }} ---> valid {{#var | $VarName | = | 1 }} ---> valid {{#var | Var Name | = | 1 }} ---> valid {{#var | VarName! | = |1 }} ---> valid {{#VarName | = | 1 }} ---> valid {{#$VarName | = | 1 }} ---> valid {{#Var Name | = | 1 }} ---> not valid {{#VarName! | = | 1 }} ---> not valid
OperatorsEdit
Both #op and #var support all of these operators, excluding the variable assignment operators which are supported by #var only.
{{#var a operator b}} {{#op a operator b}} {{#a operator b}}
operator | Action |
---|---|
Variable assignment operatorsEdit | |
@ | The following variable assignment operators may be preceded with the @ modifier, which will cause the operation to be silent (i.e. not return a value). |
= | Assign value b to variable a and return the value. |
+= | Assign the sum of variable a and value b to variable a and return the value. |
-= | Assign the difference of variable a and value b to variable a and return the value. |
*= | Assign the product of variable a and value b to variable a and return the value. |
/= | Assign the quotient of variable a and value b to variable a and return the value. |
.= | Assign the concatenation of variable a and value b to variable a and return the value. |
[]= | Assign value b to a specific element in array a |
<- | Copy the contents of var value b to variable a and return value of value b (Useful for copying arrays) |
<=> | variable a will become an alias for variable value b. In effect they are the same variable with two names. Returns value. |
The following operators do not take a third parameter and do not use the @ modifier | |
++ | Increment variable a by one and return the value. |
-- | Decrement variable a by one and return the value. |
Arithmetic operatorsEdit | |
+ | returns a + b |
- | returns a - b |
* | returns a * b |
/ | returns a / b |
^ | returns the a to the bth power |
mod | returns the remainder of a / b |
Bitwise operatorsEdit | |
& | returns bits that are set in both a and b |
? | returns bits that are set in either a or b. (? was | in Winter 2.0.0) |
xor | returns bits that are set in either a or b but not both |
<< | returns bits of a shifted b steps to the left (each step means "multiply by two") |
>> | returns bits of a shifted b steps to the right (each step means "divide by two") |
Logic operatorsEdit | |
== | Returns 1 if a is equal to b, otherwise returns 0 |
!= | Returns 1 if a is not equal to b, otherwise returns 0 |
< | Returns 1 if a is less than to b, otherwise returns 0 |
> | Returns 1 if a is greater than to b, otherwise returns 0 |
<= | Returns 1 if a is less than or equal to b |
>= | Returns 1 if a is greater than or equal to b |
and | Returns 1 if a and b are true |
or | Returns 1 if a or b are true |
Control StructuresEdit
Control structures affect program flow. The syntax for these commands is slightly modified; instead of using one pipe to delineate fields, a double pipe is used. Beginning with Winter 2.0, any field of a structure may contain nested structures.
The following control structures are available in Winter:
#if #while #repeat #for #foreach
#ifEdit
If provides the basic program branching needed in any programming language.
{{#if | bool || evaluate & return if true }} {{#if | bool || evaluate & return if true || evaluate & return if false }}
In Winter 2 the #if statement is now a true control structure so double pipes must be used. Previously single pipes were used because #if was a function. However, since all function parameters are evaluated before being passed to the function, both parameters were evaluated regardless of which was returned. If you desire this functionality you may use the #iff function. For backwards compatibility #if will rewrite statements containing no double pipes to an #iff function.
#repeatEdit
A very simple type of loop. #repeat evaluates and returns the expression for count iterations.
{{#repeat | count || expression }}
#whileEdit
Evaluates and returns the expression as long as bool evaluates to true. If the initial value of bool is false the expression will not be evaluated.
{{#while | bool || expression }}
#forEdit
for is a special kind of while loop. First initialize is evaluated. Then while bool evaluates to true, expression is evaluated and returned. Before bool is tested again, step is evaluated.
{{#for | initialize || bool || step || expression }}
Example:
{{#for | {{#a @= 1}} || {{#a <= 10 }} || {{#a ++}} || Counter: {{#a}} }}
Gives: {{#for | {{#a @= 1}} || {{#a <= 10 }} || {{#a ++}} || Counter: {{#a}} }}
#foreachEdit
Foreach is for traversing arrays and is similar to its PHP counterpart.
{{#foreach | array || expression }} {{#foreach | array || value var name ||expression }} {{#foreach | array || key var name || value var name ||expression }}
The expression will be evaluated for each value contained within the array. During each iteration certain "magic variables" will be set. The names of those variables depend on if value var name and key var name are set.
Magic variables
_key ---> always contains the text of the key name _value ---> always contains the value of the specific array item _k OR key var name ---> contains the text of the key name _v OR value var name ---> contains the value of the specific array item
FunctionsEdit
Functions are defined using #function.
{{#function | name || code }}
Any valid Winter code may be contained within a function declaration, including other function declarations. If a function name is already defined, it will be overwritten by the new declaration. Variables within a function are local to the function only.
ParametersEdit
Parameters are passed to functions via "magic variables" which are set when the program code is evaluated. The variable names are cardinal numbers corresponding to their order in the function call, e.g. the first parameter is named 1, the 2nd is named 2, and so on.
This example displays a familiar message:
{{#function | foo || Hello, {{#1}} }} {{#foo | World! }}
Escape CharactersEdit
The following escape characters may be used in any expression. They are evaluated after the expression is read but before it is parsed. This is the only way to pass { | } characters on to functions.
Escape Char Equivalent ----------- ---------- ^! | ^( { ^) } ^[ {{ ^] }} ^_ ^ ^. (nothing)
Beginning in Winter 2.0.1 escape characters are evaluated by the innermost function first, as opposed to in older versions where the outermost function evaluated the escape character first.
Special tagsEdit
<winterprewiki>Edit
<winterprewiki> is used to execute code before MediaWiki gets a chance to evaluate it. This is useful for tasks such as setting dynamic categories, setting template parameter values, and generating custom HTML.
<nowinter>Edit
The <nowinter> tag prevents Winter from evaluating any text inside of a block defined by the tags. During the parsing stage of the Winter engine, <nowinter> blocks are replaced with html comments.
Function ReferenceEdit
Arithmetic FunctionsEdit
#add, #subtract, #multiply, #divideEdit
Each of these four functions have the same syntax and general operation principle; they expect a list of numeric values and perform simple arithmetic on them from left to right.
{{#add | value 1 | value 2 | ... | value n }} ---> returns sum {{#subtract | value 1 | value 2 | ... | value n }} ---> returns difference {{#multiply | value 1 | value 2 | ... | value n }} ---> returns product {{#divide | value 1 | value 2 | ... | value n }} ---> returns quotient
#opEdit
Performs an operation or operations.
{{#op | value 1 | operator | value 2}} {{#op | value 1 | operator 1 | value 2 | operator 2 | value 3 | ... | value n |operator n | value n+1 }}
Op also supports a very simple expression syntax (This is identical to #formula in Winter v1).
{#op | simple expression}}
Simple expression is a mathematical expression which expects a very rigid structure:
- There must be a value on each side of each operator or parenthesis.
- Each operator and value must be separated by white space.
- There are only two orders of operations:
- Operations within matched parentheses are evaluated first, from the innermost set outward.
- Then operators are evaluated from left to right.
Here are two sets of operations. Each operation in each set is equivalent to the other operations in the set.
{{#op | 1 | + | 2 }} {{#op | 1 + 2 }} {{#op 1 + 2 }}
{{#op | 1 | + | 2 | + | 3 }} {{#op | 1 + ( 2 + 3 ) }} {{#op 1 + 2 + 3 }}
These are not equivalent:
{{#op | 1 | + | 2 | * | 3 }} ---> returns 9 {{#op | 1 + ( 2 * 3 ) }} ---> returns 7
Array FunctionsEdit
#arrayEdit
Creates an array and sets its values {{#array | array name |}} {{#array | array name | list }}
Any element in the list may also define the array key using the => operator.
{{#array | array name | key => value }}
Examples:
{{#array | foo | abc | 123 | yellow => banana | " red " => " apple " }}
Array foo will contain
[0] => "abc" [1] => "123" [yellow] => "banana" [ red ] => " apple "
#array_rand and #array_rand_valueEdit
Returns random elements from an array. #array_rand returns the elements as keys, #array_rand_values returns them as values. Both use the same syntax.
{{#array_rand | array }} ---> Returns a single element {{#array_rand | array | count }} ---> Returns a list of count number of elements
#countEdit
Returns the number of elements in a list or an array
{{#count | element1 | element2 | ... | elementN }} {{#count | array }}
#explodeEdit
Splits a string by a delimiter and either returns the values as a list or array
{{#explode | delimiter | string }} {{#explode | delimiter | string | array }}
Added in Winter 2.1.0
#implodeEdit
Converts an array or list into a string using delimiter to separate elements.
{{#implode | delimiter | array }} {{#implode | delimiter | element1 | element2 | ... | elementN }}
Added in Winter 2.1.0
#sort and other sorting functionsEdit
Winter has a number of sorting functions available, all of which operate similarly.
{{#sort | array name }} {{#sort | array name | sort flags }}
Sorts the contents array variable array name. Returns nothing on success and will display an error message on failure. Sort flags will tell the function to sort primarily either numerically or alphabetically. The two acceptable values are #string or #number.
You may also sort lists which have more than one element. In this case the sorted list will be returned.
{{#sort | list })
List of sorting functions
arsort - Reverse sort an array and maintain index association asort - Sort an array and maintain index association natsort - Natural order sort krsort - Reverse sort an array by key ksort - Sort an array by key sort - Sort an array rsort - Reverse sort an array
Logic Functions
Note: These functions evaluate all parameters regardless of the value returned. They should only be used for simple text substitution.
#iff
Simple if/then/else function. Depreciated in favor of #if
{{#iff | bool | evaluate; return if true }} {{#iff | bool | evaluate; return if true | evaluate; return if false }}
#ifeq and #ifneq
These functions test for equality. Depreciated in favor of #if
{{#ifeq | value 1 | value 2 | evaluate; return if equal }} {{#ifneq | value 1 | value 2 | evaluate; return if not equal }}
#not
Returns the boolean opposite of the value.
{{#not | bool }}
String Functions
#str_replace
Replaces part of a string with another string
{{#str_replace | needle | replacement | haystack }}
Replaces each occurrence of needle in haystack with replacement.
#strlen
Returns the length of the string. {{#strlen | string }}
#strpos
Returns the location of a substring in a string
{{#strpos | haystack | needle }}
On success a numeric value will be returned. On failure an empty string will be returned. The first character is at position 0.
#strtolower and #strtoupper
Returns a strings with the letters set to the specified case -- specifically lower or upper case
{{#strtolower | string }}
#substr
Returns a specified substring
{{#substr | string | start }} {{#substr | string | start | end }}
If the end is not specified, everything from start to the end of the string will be returned. The first character is at position 0. You may also use negative numbers to indicate the counting should be done from the right side of the string, not the left.
#trim, #ltrim and #rtrim
Trims whitespace from the end of a string
{{#trim | string }} ---> removes whitespace at the beginning and end of the string {{#ltrim | string }} ---> removes whitespace at the beginning of the string {{#rtrim | string }} ---> removes whitespace at the end of the string
#ucfirst
Capitalizes the first letter of the string.
{{#ucfirst | string }}
#urlencode
Urlencodes a string
{{#urlencode | string }}
Added in Winter 2.1.0
Variable Functions
#isset
Returns 1 if the variable is set, 0 if it is not set
{{#isset | variable name }}
#setvar
Sets the value of a variable or array element. Depreciated in Winter 2.0 in favor of #var operators.
{{#setvar | variable name | value }} {{#setvar | array name | x-index | value }} {{#setvar | array name | x-index | y-index | value }}
#unsetvar
Destroys a variable.
{{#unset | variable name }}
#var
Returns a variable or array value.
{{#var | variable name }} {{#var | array name | x-index }} {{#var | array name | x-index | y-index }}
Performs an operation on a variable.
{{#var | variable name | operator | value }} {{#var | variable name | operator | value | operator 2 | value 2 | ... | operator n | value n }}
Other Functions
#keep_nl
Prevents newlines with spaces following them from being removed.
{{#keep_nl}}
Added in Winter 2.1.0
#comment
Doesn't evaluate text contained within; returns nothing.
{{#comment | comment text }}
Alternative comment syntax
Since Winter 2.0.2 you may also use this alternative comment syntax.
{{#| comment text }}
Prior to 2.0.1 #comment was an alias for #null; evaluates text but returns nothing.
#date
Returns a string formatted with PHP date() function
{{#date | date_string }} {{#date | date_string | time }}
Added in Winter 2.1.0
#debug
Returns some information on the state of the Winter engine including current operation count, nesting level, defined functions and defined variables. Primarily for use while debugging program code.
{{#debug}}
#error
Returns a standard formatted Winter error message.
{{#error | message}}
#eval
Evaluates the code contained within. Useful for evaluating complex code which has been generated at runtime.
{{#eval | Winter code}}
#html_to_xml
Converts HTML tags to tags which are readable using #xml_xpath; specifically it prepends xml_ to the front of any html tag (e.g. <b> becomes <xml_b>)
{{#html_to_xml | text with html }}
#include and #include_raw
Includes the text from another page. #include runs text through the Winter engine. #include_raw does not. Wikitext markup is not interpreted during this stage; if you need the content to be formatted by MediaWiki you should use the #include command within a <winterprewiki> block.
{{#include | wiki page to include}} {{#include_raw | wiki page to include}}
Added in Winter 2.2.0
#microtime
Returns a string with clock's microseconds followed by a space, followed by the seconds past the Unix epoch
{{#microtime}}
Added in Winter 2.1.0
#nocache
Prevents the page from being cached so that each time the page is viewed the code must be evaluated again. Necessary for dynamic pages.
{{#nocache}}
#noeval
Converts { | } tags to their html entities, causing Winter to ignore the code but allow it to display correctly on the page.
{{#noeval | code }}
#null
Evaluates any parameters but returns nothing.
{{#null | code}}
#rand
Returns a random number
{{#rand}} {{#rand | upper limit}} {{#rand | lower limit | upper limit}}
The default lower limit is 0 and the default upper limit is the server side PHP configuration setting RAND_MAX.
#request_var
Returns the value of a variable sent via the HTTP request.
{{#request_var | varname }}
Added in Winter 2.1.0
#set_param_default
Sets the default wiki template parameter value if it has not been set by the calling page.
{{#set_param_default | parameter name | value }}
This function takes the place of #default which has been depreciated in Winter 2.0
#show_page_text
Displays the original page text in a <pre> box
{{#show_page_text}}
Added in Winter 2.1.0
#str_replace_all
Performs a substring replace across the entire wiki page text.
{{#str_replace_all | needle | replacement }}
This function takes the place of #define which has been depreciated in Winter 2.0
#template_var
Returns the template parameter variable associated with a certain ID
{{#template_var | varname | templateID }}
You can obtain the templateID if the variable WinterTemplate has been set in the template call. If it has, the variable WinterTemplateID will be set to the ID.
Example
{{TemplateName | foo=bar | WinterTemplate}}
Template:foo
{{#template_var | foo | {{{WinterTemplateID}}} }}
Added in Winter 2.1.0
#time
Returns the time in seconds since the Unix epoch
{{#time}}
Added in Winter 2.1.0
#to_str and #to_int
Converts an alphanumeric string to a specific type.
{{#to_int | value }}
Added in Winter 2.1.0
#version
Returns the current Winter version
{{#version}}
Added in Winter 2.1.0
#wordwrap
Wraps text at word breaks
{{#wordwrap | string | length }}
Added in Winter 2.1.0
#xml_xpath
Runs an XPath query on XML data and returns the results as a list.
{{#xml_xpath | xml data}}
Understanding Winter
Getting the most out of Winter requires understanding how both the Winter and MediaWiki parsing engines operate.
The Winter Parsing Engine
The Winter parsing engine operates by recursively evaluating each function. The code is initially parsed and formatted in such a way that it can be easily traversed using regular expressions. <nowinter> blocks are removed during this step and the Simple shortcut syntax is implemented.
Shortcut syntaxes
Some functions -- especially variable and operator functions -- may actually be shortcuts for a more standardized Winter syntax. When these function are called, they return Winter code which is processed by the Winter engine again before returning a value. These shortcuts make coding and readability easier but do increase the amount of operations needed and may put an unnecessary strain on the server in high load situations, especially on dynamic pages.
All #op operations can be simplified into {{#op | a | operator | b }} type syntax which will be evaluated by PHP directly.
Preprocessor shortcuts
{{#command}} --> {{#command|}} {{#command a b c}} --> {{#command|a|b|c}}
Runtime shortcuts
{{#if | a | b | c }} --> {{#iff | a | b | c }} {{#varname | = | c }} --> {{#var | varname | = | c }} {{#var | varname | + | c }} --> {{#op | varname_value | + | c }} {{#op 1 + 2 - 3 * 4 }} --> {{#op | {{#op | {{#op | 1 | + | 2 }} | - | 3 }} | * | 4 }}
Rewriting Winter code on the fly
Because Winter code has gone through an initial formatting phase before being passed to the parsing engine, creating Winter code on the fly may not work as expected, especially complex code which includes nested function calls or shortcuts applied during formatting. Using #eval will guarantee your code works properly.
Winter and MediaWiki
Winter is a MediaWiki parser extension. Winter attaches itself to the hook ParserBeforeTidy . This means before being passed to Winter the wiki code has already been rendered into HTML, templates have been loaded, and template variables have been substituted. In general the page is almost ready for display. Because the page is almost completely rendered, using Winter commands to generate wiki markup may not always have the intended results.
Beginning in 2.1.0, there is the option of executing Winter code before the page has been processed by MediaWiki by using <WinterPreWiki> tags. Template variables will not be replaced with their values inside of WinterPreWiki blocks because the wiki parser has not touched the text.
Processing order
- Winter - Interpret code inside of WinterPreWiki blocks
- Winter - Analyze template calls and rewrite them for use with Winter
- MediaWiki - Process Wiki markup, links, html, templates
- Winter - Interpret main Winter program code
- MediaWiki - Do final HTML tidy and display
Whitespace issues
Due to the fact Winter code is processed by MediaWiki before being parsed by the Winter engine, whitespace often has significance. One especially problematic issue for Winter coders prior to 2.10 was the fact that MediaWiki treats every line which begins with space as a <pre> block. This means Winter code must always be left aligned unless inside of a <nowiki> block.
Beginning with v2.1.0, Winter gets around the problem forcing left alignment by removing line breaks if they are followed by a space. To preserve the newline, either use {{#keep_nl}} which will prevent all newline characters from being replaced, or begin the line with the ^. escape character which evaluates to an empty string.
Winter and Parser Function Extensions
Winter can be installed along-side parser extensions without problems.
Winter was originally created before parser function extensions were available. Though Winter is similar to the parser function extensions in form and function, they are two completely different systems and do not interfere with each other. However, you must take care when using them together. Parser function extensions will be evaluated before being passed to Winter, so nesting Winter functions within Parser functions may not work as expected. It is recommended you keep the code types separate as much as possible to avoid confusion. Winter provides all functionality offered by parser functions so there should no need to use them together. Intertwining parser functions with Winter functions within <winterprewiki> blocks is especially recommended against.
Example of Winter and Parser Functions used together
All of these expressions return no. {{#ifeq: 1 | 2 | yes | no}} {{#iff | {{#op | 1 == 2 }} | yes | no }} {{#iff | {{#op | 1 == 2 }} | yes | {{#ifeq: 1 | 2 | yes | no}} }} {{#ifeq: 1 | 2 | yes | {{#iff | {{#op | 1 == 2 }} | yes | no }} }}
Example of unexpected resultsEdit
{{#expr: 1 + 1}} => 2 {{#op| 1 + 1}} => 2 {{#expr: {{#expr: 1 + 1}} + 1}} => 3 {{#expr: {{#op| 1 + 1}} + 1}} => error {{#op| {{#expr: 1 + 1}} | + | 1}} => 3
The use of # explainedEdit
The reason each command in Winter begins with a # after the double brace is because MediaWiki ignores templates which start with #. Almost all other characters will cause the code to turn into a template reference.
Reusing code with templates and #includeEdit
MediaWiki supports the inclusion of one page within another using templates. Templates can be used to include Winter code or data within a script. Some example uses could be to include a library of common functions or some XML data to be processed using #xml_xpath.
Code within templates is not evaluated until after the template has been inserted on the calling page.
Beginning with Winter 2.2.0, you may use #include to evaluate other page contents before inserting. or use #include_raw to insert contents without evaluating. When using #include, the wikitext will not be converted to HTML; if formatting is important, you must use #include inside of a <WinterPreWiki> block.
Using MediaWiki template variablesEdit
The MediaWiki parsing engine evaluates template variables before they are passed to Winter. This means you cannot use Winter to generate arbitrary template variable names on the fly. Beginning in 2.1.0 template calls are analyzed before being passed to MediaWiki and template parameter variables are saved into the _templates variable and are also accessible with #template_var.
AppendicesEdit
List of Error CodesEdit
Error # | Error message text |
---|---|
1 | Maximum nesting level ($wgWinterMaxNesting) exceeded |
2 | Maximum number of operations ($wgWintermaxOperations) reached |
3 | Syntax error in (functionString). |
4 | function has been disabled by the administrator |
5 | Maximum number of iterations ($WinterMaxIterations) reached |
6 | Syntax error in while statement |
7 | Maximum number of iterations ($WinterMaxIterations) reached |
8 | First parameter must be numeric |
9 | Syntax error in repeat statement |
10 | Maximum number of iterations ($WinterMaxIterations) reached |
11 | Syntax error in for statement |
12 | Syntax error in foreach statement |
13 | Error defining function functionname. |
14 | Syntax error in functionString statement |
15 | Syntax error in eval statement |
16 | Divide by Zero |
17 | Syntax error in variable: varName statement |
18 | Syntax error in operation statement - parentheses must match |
19 | Divide by Zero |
20 | operator operator not defined in (functionString) |
21 | Divide by Zero |
22 | There was a problem sorting the array with functionName |
23 | Array name larger than maximum number of allowed iterations ($WinterMaxIterations) in foreach |
Command IndexEdit
- #add
- #array
- #array_rand
- #array_rand_value
- #arsort
- #asort
- #comment
- #count
- #debug
- #default
- #define
- #divide
- #error
- #eval
- #for
- #foreach
- #html_to_xml
- #if
- #ifeq
- #iff
- #ifneq
- #include
- #include_raw
- #isset
- #keepnl
- #krsort
- #ksort
- #ltrim
- #multiply
- #natsort
- #nocache
- #noeval
- #not
- #null
- #op
- #preg_replace
- #rand
- #repeat
- #rsort
- #rtrim
- #set_param_default
- #setvar
- #sort
- #str_replace
- #str_replace_all
- #strip_tags
- #strlen
- #strpos
- #strtolower
- #strtoupper
- #substr
- #subtract
- #trim
- #ucfirst
- #unsetvar
- #var
- #while
- #xml_xpath