Jump to content

Extension:ArrayFunctions

From mediawiki.org
Revision as of 14:25, 10 February 2023 by Xxmarijnw (talk | contribs)
MediaWiki extensions manual
ArrayFunctions
Release status: stable
Implementation Parser function
Description Provides a set of pure parser functions that operate on arrays
Author(s) Marijn van Wezel (Wikibase Solutions)
Latest version 1.1.0 (2023-02-03)
Compatibility policy Master maintains backward compatibility.
MediaWiki >=1.35.6
PHP >=7.4
Database changes No
Composer wikibase-solutions/array-functions
  • $wgArrayFunctionsMaxPipelineLength
  • $wgArrayFunctionsEnableErrorTracking
  • $wgArrayFunctionsMaxRangeSize
  • $wgArrayFunctionsForeachIterationLimit
Licence GNU General Public License 2.0 or later
Download
Translate the ArrayFunctions extension if it is available at translatewiki.net
Issues Open tasks · Report a bug
Presentation at SMWCon 2022 talking about ArrayFunctions

The ArrayFunctions extension creates an additional set of pure, Parsoid-compatible (see here) parser functions that perform operations on arrays. These parser functions are pure, meaning they do not modify any previously defined arrays and only return a result based on their input arguments.

This extension defines the following parser functions, Lua functions and magic words:

Group Functions
Construct an array or value #af_bool, #af_float, #af_int, #af_list, #af_object, #af_split, AF_EMPTY, mw.af.export
Extract information from an array #af_count, #af_exists, #af_get, #af_isarray, #af_print
Create an array from an existing array #af_keysort, #af_push, #af_set, #af_slice, #af_sort, #af_unique, #af_unset
Iterate over an array #af_foreach, #af_join, #af_map
Miscellaneous functions #af_if, #af_template

Functions

af_bool

This parser function casts a string to a boolean. This is useful for creating an array containing a boolean.

Description

{{#af_bool: value }}

Parameters

value : string or boolean
The value to cast to a boolean.

Return values

Returns the casted boolean.

Examples

Create an opaque representation of a boolean
{{#af_bool: yes }}, {{#af_bool: no }}, {{#af_bool: true }}
boolean__^__1, boolean__^__0, boolean__^__1
Create an array containing a boolean
{{#af_print: {{#af_list: {{#af_bool: yes}} }} }}
  • 0: true

af_count

This parser functions counts the number of values in an array.

Description

{{#af_count: array | recursive=recursive }}

Parameters

array : array
The array to count.
recursive : boolean, default=false
Whether to count items recursively. Note that elements containing a list are also counted (see examples below).

Return values

The number of items in the array.

Examples

Count the number of items in a one-dimensional list
{{#af_print: {{#af_count: {{#af_list: a | b | c }} }} }}
3
Count the number of items in a multi-dimensional list
{{#af_print: {{#af_count: {{#af_list: {{#af_list: a | b }} | {{#af_list: c | d }} }} }} }}
2
Recursively count the number of items in a multi-dimensional list
{{#af_print: {{#af_count: {{#af_list: {{#af_list: a | b }} | {{#af_list: c | d }} }} | recursive=true }} }}
6

af_exists

This parser function checks whether the given key or index exists in the given array.

Description

{{#af_exists: array | key }}

Parameters

array : array
The array to check.
key : string or int
The key to check.

Return values

Returns true if array contains key, false otherwise.

Examples

Check if a key exists
{{#af_print: {{#af_exists: {{#af_object: hello=world }} | hello }} }}
true
Check if an index exists
{{#af_print: {{#af_exists: {{#af_list: a | b | c }} | 2 }} }}
true
Check if a nested key exists
{{#af_print: {{#af_exists: {{#af_get: {{#af_list: a | {{#af_list: b | c }} }} | 1 }} | 2 }} }}
false

af_float

This parser function casts a string to a float. This is useful for creating an array containing a float.

Description

{{#af_float: value }}

Parameters

value : string or float
The value to cast to a float.

Return values

Returns the casted float.

Examples

Create an opaque representation of a float
{{#af_float: 1.298 }}, {{#af_float: 0 }}
float__^__1.298, float__^__0
Create an array containing a float
{{#af_print: {{#af_list: {{#af_float: 1.298 }} }} }}
  • 0: 1.298

af_foreach

This parser function provides a way to iterate over arrays.

Description

{{#af_foreach: array | key_name | value_name | body }}

Parameters

array : array
The array over which to iterate.
key_name : string, default=null
The name to use for the key.
value_name : string, default=null
The name to use for the value.
body : string
The body to return for each iteration.

Return values

Returns the resulting wikitext.

Examples

Iterate over a list
{{#af_foreach: {{#af_list: John | Steve | Harry }} | | name | Hello, {{{name}}}!<br/> }}
Hello, John!
Hello, Steve!
Hello, Harry!
Iterate over an object
{{#af_foreach: {{#af_object: Hello=John | Hi=Steve | Welcome=Harry }} | greeting | name | {{{greeting}}}, {{{name}}}!<br/> }}
Hello, John!
Hi, Steve!
Welcome, Harry!

af_get

This parser function retrieves the element with the given index from the given array. If the index does not exist, the empty string is returned.

Description

{{#af_get: array | *indices }}

Parameters

array : array
The array in which to index.
*indices : string
The index. Multiple indices can be given to index nested arrays.

Return values

Returns the indexed value, or the empty string if the index does not exist.

Examples

Get a top-level element
{{#af_get: {{#af_list: a | b | c }} | 1 }}
b
Get a subarray
{{#af_print: {{#af_get: {{#af_list: a | {{#af_list: b | c }} }} | 1 }} }}
  • 0: b
  • 1: c
Get a nested element
{{#af_get: {{#af_list: a | {{#af_object: hello=world }} }} | 1 | hello }}
world

af_if

This parser function selects one of two alternatives based on the given predicate.

Description

{{#af_if: predicate | consequent | alternative }}

Parameters

predicate : boolean
The predicate.
consequent : string
The value to return if the predicate holds (i.e. is true).
alternative : string, default=""
The value to return if the predicate does not hold (i.e. is false).

Return values

Returns the consequent if the predicate holds, or the alternative if it is given and the predicate does not hold.

Examples

Check if a value is an array
{{#af_if: {{#af_isarray: not an array }} | A beautiful array! | Not an array! }}
Not an array!

af_int

This parser function casts a string to an integer. This is useful for creating an array containing an integer.

Description

{{#af_int: value }}

Parameters

value : string or int
The value to cast to an integer.

Return values

Returns the casted integer.

Examples

Create an opaque representation of an integer
{{#af_int: 42 }}, {{#af_int: -12 }}
integer__^__42, integer__^__-12
Create an array containing an integer
{{#af_print: {{#af_list: {{#af_int: -129}} }} }}
  • 0: -129

af_isarray

This parser function checks if the given value is an array.

Description

{{#af_isarray: value }}

Parameters

value : mixed
The value to check.

Return values

Returns true if value is an array, false otherwise.

Examples

Check if an array is an array
{{#af_print: {{#af_isarray: {{#af_list: a | b | c }} }} }}
true
Check if a string is an array
{{#af_print: {{#af_isarray: Hello, World! }} }}
false

af_join

This parser function recursively joins the items of an array together with a given separator.

Description

{{#af_join: array | glue }}

Parameters

array : array
The array to join.
glue : string, default=""
The string used to join each item. This parameter recognises the following escape sequences:
\s for spaces
\n for newlines
\\ for backslashes

Return values

Returns the joined array.

Examples

Join a one-dimensional array
{{#af_join: {{#af_list: a | b | c }} }}
abc
Join a one-dimensional array using a separator
{{#af_join: {{#af_list: a | b | c }} | \s-\s }}
a - b - c
Join a multi-dimensional array using a separator
{{#af_join: {{#af_list: a | b | {{#af_list: c | d }} }} | \s-\s }}
a - b - c - d

af_keysort

This parser function sorts a multidimensional array based on the values of a key.

Description

{{#af_keysort: array | key | descending=descending }}

Parameters

array : array
The array to sort.
key : string
The key of the values on which the sort should be based.
descending : boolean, default=false
Whether to sort in a descending order.

Return values

Returns the sorted array.

Examples

Sort based on age
{{#af_print: {{#af_keysort: {{#af_list:
    {{#af_object: name=John | age=56 }} |
    {{#af_object: name=Harry | age=12 }} |
    {{#af_object: name=Bob | age=24 }}
}} | age }} }}
  • 0
    • name: Harry
    • age: 12
  • 1
    • name: Bob
    • age: 24
  • 2
    • name: John
    • age: 56
Sort based on age, in descending order
{{#af_print: {{#af_keysort: {{#af_list:
    {{#af_object: name=John | age=56 }} |
    {{#af_object: name=Harry | age=12 }} |
    {{#af_object: name=Bob | age=24 }}
}} | age | descending=true }} }}
  • 0
    • name: John
    • age: 56
  • 1
    • name: Bob
    • age: 24
  • 2
    • name: Harry
    • age: 12

af_list

This parser function creates a new list from the given parameters.

Description

{{#af_list: *values }}

Parameters

*values : mixed
The values for the list.

Return values

Returns the resulting list.

Examples

Create a simple one-dimensional list
{{#af_print: {{#af_list: a | b | c }} }}
  • 0: a
  • 1: b
  • 2: c
Create a multi-dimensional list
{{#af_print: {{#af_list: {{#af_list: a | b }} | {{#af_list: c | d }} }} }}
  • 0
    • 0: a
    • 1: b
  • 1
    • 0: c
    • 1: d
Create a list of objects
{{#af_print: {{#af_list:
    {{#af_object: name=Harry | age=22 }} |
    {{#af_object: name=Bobby | age=29 }}
}} }}
  • 0
    • name: Harry
    • age: 22
  • 1
    • name: Bobby
    • age: 29

af_map

This parser function applies a callback to each element of a list.

Description

{{#af_map: array | value_name | callback }}

Parameters

array : array
The array to run through the callback.
value_name : string
The name to give to the value in the callback.
callback : string
The callback to apply to each element of the array.

Return values

Returns the resulting mapped array.

Examples

Appending a string to each element
{{#af_print: {{#af_map: {{#af_list: a | b | c }} | v | {{{v}}}-appended }} }}
  • 0: a-appended
  • 1: b-appended
  • 2: c-appended
Altering list elements
{{#af_print: {{#af_map: {{#af_list: {{#af_list: a }} | {{#af_list: b }} }} | v | {{#af_push: {{{v}}} | c }} }} }}
  • 0
    • 0: a
    • 1: c
  • 1
    • 0: b
    • 1: c

af_object

This parser function creates a new object from the given parameters.

Description

{{#af_object: **values }}

Parameters

**values : mixed
The values for the object.

Return values

Returns the resulting object.

Examples

Create a simple one-dimensional object
{{#af_print: {{#af_object: a=b | b=c | c=d }} }}
  • a: b
  • b: c
  • c: d
Create a multi-dimensional object
{{#af_print: {{#af_object: head={{#af_object: title=MediaWiki | meta={{#af_list: {{#af_object: charset=UTF-8 }} }} }} }} }}
  • head
    • title: MediaWiki
    • meta
      • 0
        • charset: UTF-8

af_print

This parser function prints the given value in a human-readable format.

Description

{{#af_print: *values | end=end }}

Parameters

*values : mixed
The values to print.
end : string, default=""
The string to append to the end of each printed value. This parameter recognises the following escape sequences:
\s for spaces
\n for newlines
\\ for backslashes

Return values

Returns the value in human-readable form.

Examples

Print a boolean
{{#af_print: {{#af_bool: yes }} }}
true
Print a list
{{#af_print: {{#af_list: a | b | c }} }}
  • 0: a
  • 1: b
  • 2: c

af_push

This parser function adds the given value to the end of the list.

Description

{{#af_push: array | value }}

Parameters

array : array
The array to append the value to.
value : mixed
The value to add.

Return values

Returns the array with the value appended.

Examples

Push a value
{{#af_print: {{#af_push: {{#af_list: a | b }} | c }} }}
  • 0: a
  • 1: b
  • 2: c

af_set

This parser function sets the given value for the given index.

Description

{{#af_set: value | array | *indices }}

Parameters

value : mixed
The value to set the index to.
array : array
To array in which to set the index.
*indices : string
The index to set. Multiple indices can be given to index nested arrays.

Return values

Returns the array with the given index set to the given value.

Examples

Replace an existing value
{{#af_print: {{#af_set: d | {{#af_list: a | b | c }} | 2 }} }}
  • 0: a
  • 1: b
  • 2: d
Create a new index
{{#af_print: {{#af_set: far | {{#af_object: foo=bar }} | boo }} }}
  • foo: bar
  • boo: far
Create a new subarray
{{#af_print: {{#af_set: far | {{#af_object: foo=bar }} | boo | far }} }}
  • foo: bar
  • boo
    • far: far

af_slice

This parser function extracts a slice from the given array. Keys will be reset and reordered.

Description

{{#af_slice: array | offset | length }}

Parameters

array : array
The array to take a slice from.
offset : integer
The offset at which the slice starts. If non-negative, the slice will start at this given offset. If negative, the sequence will start that far from the end of the array.
length : integer, optional
The length of the slice. If the length is given and positive, then the slice will have that many elements in it. If the length is given and negative, then the slice will stop that many elements from the end of the array. If it is omitted, then the slice will have everything from offset up until the end of the array.

Return values

The slice.

Examples

Get the first two elements
{{#af_print: {{#af_slice: {{#af_list: a | b | c }} | 0 | 2 }} }}
  • 0: a
  • 1: b
Get the last element
{{#af_print: {{#af_slice: {{#af_list: a | b | c }} | -1 }} }}
  • 0: c

af_sort

This parser function sorts the given list.

Description

{{#af_sort: array | descending=descending }}

Parameters

array : array
The array to sort.
descending : boolean, default=false
Whether to sort the list in descending order.

Return values

Returns the sorted list.

Examples

Sort a list in ascending order
{{#af_print: {{#af_sort: {{#af_list: b | c | a }} }} }}
  • 0: a
  • 1: b
  • 2: c
Sort a list in descending order
{{#af_print: {{#af_sort: {{#af_list: b | c | a }} | descending=true }} }}
  • 0: c
  • 1: b
  • 2: a

af_split

This parser function splits the given string based on a delimiter.

Description

{{#af_split: string | delimiter }}

Parameters

string : string
The string to split.
delimiter : string, default=","
The delimiter to use. This parameter recognises the following escape sequences:
\s for spaces
\n for newlines
\\ for backslashes

Return values

Returns the resulting list.

Examples

Split a string based on commas
{{#af_print: {{#af_split: a, b, c }} }}
  • 0: a
  • 1: b
  • 2: c
Split a sentence into words
{{#af_print: {{#af_split: Lorem ipsum dolor et | \s }} }}
  • 0: Lorem
  • 1: ipsum
  • 2: dolor
  • 3: et

af_template

This parser function will invoke the given template and pass the values in the given array as (named) parameters.

Description

{{#af_template: name | data }}

Parameters

name : string
The name of the template to invoke. If no namespace is given, it is assumed the page is in the template namespace, otherwise the given namespace is used. The page must exist, must be includable and must be readable by the user, otherwise an error is given.

Return values

The expanded template.

Examples

Invoking a template with a list
{{#af_template: Echo | {{#af_list: a | b }} }}
{{Echo|a|b}}
Invoking a template with an object
{{#af_template: Echo | {{#af_object: foo=bar | boo=far }} }}
{{Echo|foo=bar|boo=far}}

af_unique

This parser function removes duplicate values from the given array. This function does not reset keys.

Description

{{#af_unique: array }}

Parameters

array : array
The array from which to remove duplicates.

Return values

Returns the array with duplicates removed.

Examples

Remove duplicates from an array
{{#af_print: {{#af_unique: {{#af_list: a | a | b | c | b }} }} }}
  • 0: a
  • 2: b
  • 3: c

af_unset

This parser function removes the value associated with the given index from the array and returns the result. Numeric keys are not reset after calling this function.

Description

{{#af_unset: array | *indices }}

Parameters

array : array
The array from which to remove the given key.
*indices : string
The index to remove. Multiple indices can be given to index nested arrays.

Return values

Returns the array with the given index removed.

Examples

Remove a top-level index
{{#af_print: {{#af_unset: {{#af_list: a | b | c }} | 2 }} }}
  • 0: a
  • 1: b
Remove a top-level index, keys not reset
{{#af_print: {{#af_unset: {{#af_list: a | b | c }} | 1 }} }}
  • 0: a
  • 2: c
Remove a nested index
{{#af_print: {{#af_unset: {{#af_object: foo={{#af_object: bar=quz | far=buz }} }} | foo | bar }} }}
  • foo
    • far: buz

Scribunto

This extension is particularly useful in combination with Lua, as it can be used to create the array containing data required for the presentation of the page. This array can be exported to work with ArrayFunctions:

local p = {};

function p.world()
	return mw.af.export({
		["Hello"] = "World"
	});
end

return p;

This module may then be invoked like so:

{{#af_print: {{#invoke: Hello | world }} }}
  • Hello: World

Magic words

The extension defines a number of magic words (variables).

AF_EMPTY

This magic word returns the empty array. This is useful, because it is not possible to create an empty array with #af_list or #af_object.

Description

{{AF_EMPTY}}

Return values

Returns the empty array.

Installation

  • Download and move the extracted ArrayFunctions folder to your extensions/ directory.
    Developers and code contributors should install the extension from Git instead, using:
    cd extensions/
    git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/ArrayFunctions
    
  • Add the following code at the bottom of your LocalSettings.php file:
    wfLoadExtension( 'ArrayFunctions' );
    
  • Yes Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

FAQ

How can I define an array to be used throughout a page?

It is not possible to directly define an array to be used throughout a page, because this would require sequential processing of extension tags, which is not supported by Parsoid (see Parsoid/Extension API#No support for sequential, in-order processing of extension tags). Instead, you can pass arrays around as template parameters:

{{My template|{{#af_list:a|b|c}}}}

This way, the array is available in Template:My template as {{{1}}}.

How to iterate over an array?

It is possible to iteratively access elements of an array using #af_foreach:

{{#af_foreach:{{#af_list:red|green|blue}}||color|<nowiki/>
* {{{color}}} is my favourite.
}}

The expected output from the snipped above is:

  • red is my favourite.
  • green is my favourite.
  • blue is my favourite.

How to use foreach with a delimiter?

Using #af_foreach with a delimiter is not supported. Instead, you can use the #af_map function in conjunction with the #af_join function:

{{#af_join:{{#af_map:{{#af_list:red|green|blue}}|color|* {{{color}}} is my favourite.}}|\n}}

See also