{array:id:cmd:par1:par2:par3}

Description

Experimental in-memory array (a key-value store) you build up across a template and read back. It keeps one named array per id for the whole page render. The first parameter is the array id, the second is the command, and the rest depend on that command. set writes a value at a key (an empty key appends), get reads one key, addmulti splits a string and appends each part, addset adds a number into a key (a numeric accumulator), joinset appends a value to a key with a delimiter, getall returns every value joined (optionally re-formatted and sorted), getfiltered returns only the values matching a substring. The build commands (set, addmulti, addset, joinset) print nothing, only get, getall and getfiltered produce output. Because the store is shared across the whole page by id, give each array a unique id and build it and read it in the same place.

Parameters

id required default (none)

The array name. Every array command that uses the same id reads and writes the same store, which lives for the whole page render. Choose a unique id per array so other examples on the page cannot collide with it. An empty id produces no output.

cmd required default (none)

The operation to run on the array. set writes a value at a key (an empty key appends). get reads one key. addmulti splits a string and appends each part. addset adds a number into a key (a numeric accumulator). joinset appends a value to a key, separated by a delimiter. getall returns every value joined, optionally re-formatted and sorted. getfiltered returns only the values whose text contains a substring. An unknown command produces no output.

par1 optional default (none)

First argument, meaning set by cmd. For set, addset and joinset it is the key (an empty key makes set append). For get it is the key to read. For addmulti it is the string to split. For getall it is the output template applied to each entry (the value, with _#1 standing for the value and _#2 for the key); leave it as _#1 to emit values unchanged. For getfiltered it is the substring to match.

par2 optional default (none)

Second argument, meaning set by cmd. For set, addset and joinset it is the value to store. For addmulti it is the delimiter to split on (empty splits on a dash, or parses a [..] string as a JSON array). For getall and getfiltered it is the delimiter that joins the returned entries (the literal word json joins them as a JSON array instead). Not used by get.

par3 optional default (none)

Third argument, used only by joinset and getall. For joinset it is the delimiter placed between the existing value and the appended one. For getall it is the sort order: key sorts by key ascending (numeric), rkey sorts descending, empty keeps insertion order.

Examples

virtual{array:arr_am:addmulti:apple-pear-plum:-}{array:arr_am:getall:_#1:, }
Expectedapple, pear, plum (per build run)
Actualapple, pear, plum, apple, pear, plum
addmulti splits par1 and appends each part. par2 is the delimiter: a dash here. Always pass par2; omitting it makes the engine error. Illustrative, not a verified test, because addmulti appends and the build can run more than once on a page.
virtual{array:arr_sum:addset:total:10}{array:arr_sum:addset:total:5.5}{array:arr_sum:get:total}
Expected15.5 (per build run)
Actual31
addset adds a number into a key, so two calls leave 15.5 under total. This example is illustrative, not a verified test: the array store lives for the whole page, so an accumulator like addset keeps adding every time the same code runs on a page (the reference page renders each example more than once). Give the array a fresh id and build it once per page.
virtual{array:arr_app:set::red}{array:arr_app:set::green}{array:arr_app:set::blue}{array:arr_app:getall:_#1:, }
Expectedred, green, blue (per build run)
Actualred, green, blue, red, green, blue
When the key is empty, set appends the value instead of overwriting, building a plain list you read back with getall. Illustrative, not a verified test: appends accumulate when the same build runs more than once on a page.
test{array:arr_all:set:a:red}{array:arr_all:set:b:green}{array:arr_all:getall:_#1:, }
Expectedred, green
Actualred, green
set writes one value per key, getall returns them all joined by par2. Because each set targets a fixed key, repeating the build is harmless: the keys are overwritten, not appended.
test{array:arr_srt:set:3:c}{array:arr_srt:set:1:a}{array:arr_srt:set:2:b}{array:arr_srt:getall:_#1:-:key}
Expecteda-b-c
Actuala-b-c
par3=key sorts the entries by key (ascending, numeric) before joining. The values were stored out of order but come back a-b-c.
test{array:arr_rk:set:1:a}{array:arr_rk:set:2:b}{array:arr_rk:set:3:c}{array:arr_rk:getall:_#1:-:rkey}
Expectedc-b-a
Actualc-b-a
par3=rkey sorts by key descending. Use key for ascending and leave par3 empty to keep insertion order.
test{array:arr_tpl:set:cs:Czech}{array:arr_tpl:set:en:English}{array:arr_tpl:getall:_#2=_#1:; }
Expectedcs=Czech; en=English
Actualcs=Czech; en=English
In getall, par1 is a template applied to each entry: _#1 is the value and _#2 is the key. Here it prints key=value pairs joined by a semicolon.
test{array:arr_flt:set:1:apple}{array:arr_flt:set:2:apricot}{array:arr_flt:set:3:banana}{array:arr_flt:getfiltered:ap:, }
Expectedapple, apricot
Actualapple, apricot
getfiltered returns only the values whose text contains par1 (here ap), joined by par2. banana is dropped.
virtual{array:arr_join:joinset:tags:news: }{array:arr_join:joinset:tags:events: }{array:arr_join:get:tags}
Expectednews events (per build run)
Actualnews events news events
joinset appends a value to a key, separated by par3. The first call just stores news, the second appends a space and events. Illustrative, not a verified test, for the same reason as addset: joinset accumulates if the code runs more than once on a page.
test[{array:arr_miss:set:x:1}{array:arr_miss:get:y}]
Expected[]
Actual[]
get returns an empty string when the key was never set. The square brackets are literal, added so the empty result is visible.
test{array:arr_kv:set:greeting:Hello}{array:arr_kv:get:greeting}
ExpectedHello
ActualHello
The simplest use: set writes a value at a key (par1=greeting, par2=Hello), get reads it back. Build commands like set print nothing on their own, only get produces output.