# Template Engine

# Introduction

The Template Engine always processes texts. For this purpose so-called templates are required. In a template you prepare a document for which not all values can yet be defined, such as mass mail. Certain placeholders can be set. During generation, these wildcards are replaced by correct values, which must also be passed to the Template Engine. For example, Hello {name}! is turned to Hello John Doe. Besides simple variables, also queries, loops and functions can be processed.

The Template Engine's so-called "HTML engine" can be used with all types of texts, e.g. HTML, text, XML, TeX, CSV, JSON files, and others. Furthermore, an "XLSX engine" is included. It allows the definition of templates with Excel. The output can be in xlsx, csv, and other formats. Besides Excel, there is also the "DOCX engine". It allows the definition of templates with Word. The output can be in .docx, .pdf, and other formats.

# Variables

{$foo}            - Represents a simple variable
{foo}             - Alternative: The '$' is optional in most cases
{$foo[3]}         - Represents the fourth element in the array
{$foo.bar}        - Sets the value, of a map/object with the key 'bar'
{$foo["bar"]}     - Alternative: If the key contains special characters
{$foo.bar()}      - Calls the function 'bar' for the object 'foo' and
                    represents the result
{text source=foo} - Alternative spelling for texts
{\$foo}           - Tags with a backslash after the '{' are
                    is ignored and regarded as normal text. The
                    Backslash is removed (Result: '{$foo}')
{$["foo.bar"]}    - Useful when variables do not match the syntax,
                    for example, contain a point. (**Not**
                    the same as 'foo.bar')

See Text Output (text)

# Value Types

# Numbers (Number)

All numbers are always in tens. Even negative numbers are possible.

  • Example: 0, 8129, -12, {foo.charAt(14)}

Numbers with decimal places are also possible. The decimal separator must always be the dot (.).

  • Example: 1.414213562, -2.71828, {2 * 3.14159 * r}.

The possible accuracy is derived from the double data type. (64-bit IEEE 754 floating point).

# Strings (String)

Strings are character strings. Two types of declaration are possible. Both behaviors are completely identical. Only UTF-8 character encoding is supported.

  • Example: "foo", 'bar', {'foo'.regexReplace("foo", 'bar')}

Within double quotes ("), single quotes (') can be used as well as vice versa.

  • Example: "fo'o", 'ba"r', {"f'o".regexReplace("'", '"')}

# Boolean Values

Boolean values can be true or false. All characters must be written in lower case.

  • Example: {if foo == true}bar{/if}

# Date Values (Date)

A date value represents a date. A date can only be passed as a variable by the implementation or created by functions like getDate.

  • Example: {getDate()}

# Lists (Array)

A list can contain several elements of other types, but also other lists. Lists can only be passed by the environment. No new list can be created at runtime of the Template Engine. Lists start at 0, so the first element defined with 0 is accessed.

The length of a list can be requested with function length.

  • Example: {myList.length()}

An element of the list can be accessed with the [] operator.

  • Example: {myList[5]}

Lists can be run through with tag loop.

  • Example: {loop source=myList}{_entry}{/loop}

# Map (Object)

A map is a simple key/value assignment. Key and value can contain any types. Maps can only be passed by the environment. No new map can be created at runtime of the Template Engine.

The length of a map can be requested with function length.

  • Example: {myMap.length()}

An element of a map is accessed with the . operator or the [] operator. The latter also allows special characters in map's key, which is specified with a string.

  • Example: {myMap.element1}, {myMap["ele.ment"]}

Whether an element is available in a map can be determined using the contains function.

  • Example: {myMap.contains("element1")}

# Functions

Functions are executable logics provided to be used by the Template Engine. Usually they load data or change the values of variables. Functions can take values (here parameters), that change behavior.
Syntax: {[variable.]functionname([parameter[, parameter]])}

  • Examples:

    {foo.toUpperCase()}
    {$foo[9].toLowerCase()}
    {text source=foo.trim()}
    {foo.replaceAll("bar", "boo")}
    

There is a number of Build-In functions. Plugins can add custom functions or overwrite, extend, or change existing ones.

# Arithmetic

With the Template Engine it is also possible to perform simple calculations. The following operators are supported:

Operator Description
Negative sign -
Syntax: -<Oparand>
Returns the negative value of an operand. The operand must be numeric.
Addition +
Syntax: <Oparand>&<Oparand>
Returns the sum of the operands
Subtraction -
Syntax: <Oparand>-<Oparand>
Returns the difference of the operands
Multiplication *
Syntax: <Oparand>*<Oparand>
Returns the product of the two operands
Division /
Syntax: <Oparand>/<Oparand>
Returns the quotient from the division
Brackets (<Expression>)
Syntax: <Operator>(<Expr>)<Operator>
Parentheses can be used for calculations in any complicated way.

Operator Sequence

  • Examples:

    {foo + 1}
    {foo * bar}
    {(foo.bar["num"] + 7) * 0.5}
    {1 / 0}                     // "Infinity"
    {foo.charAt(2 * 2)}
    {(5*7).format("%.0f")}      // Output without decimal places
    {{(5*7).format("%.2f")}}    // Output with two decimal places
    

# Boolean Operators

Boolean operators determine or compare truth values, for example to use them in an If statement (if). The return value of one of these operators is therefore always a truth value (Boolean).

Operator Description
equal ==
Syntax: <Operand>==<Operand>
Returns true if both operands have the same value. Supported are numbers, strings, boolean values and date values.
not equal !=
Syntax: <Operand>!=<Operand>
Returns true if the operands have different values. Supported are numbers, strings and boolean values.
greater >
Syntax: <Operand>><Operand>
Returns true if the left operator is "greater" than the right operator. Only numbers are supported.
less <
Syntax: <Operand><<Operand>
Returns true if the left operator is "less" than the right operator. Only numbers are supported.
greater or equal >=
Syntax: <Operand>>=<Operand>
Returns true if the left operator is "greater" than or equal to the right operator.
Alternatively, &gt;= can be used. Only numbers are supported.
less or equal <=
Syntax: <Operand><=<Operand>
Returns true if the left operator is "less" than or equal to the right operator.
Alternatively, &lt;= can be used. Only numbers are supported.
and &&
Syntax: <Operand>&&<Operand>
Returns true if both operands are true (True). Numbers greater than 0 are evaluated as true and 0 or less than false.
Alternatively, &amp;&amp; can be used.
or &#124;&#124;
Syntax: <Operand>&#124;&#124;<Operand>
Returns true if either the left, the right, or both operators are true. Numbers greater than 0 are evaluated as true and 0 or less than false.
not !
Syntax: !<Operand>
Reverses the truth value, false becomes true and true becomes false. Numbers greater than 0 are evaluated as true and 0 or less than 0 as false.

Operator Sequence

Examples:

    {"foo" == "foo"}           => true
    {42 >= 42}                 => true
    {true || false}            => true
    {true && false}            => false
    {42 > 2 && "foo" != "bar"} => true
    {if "foo".length() > 2}foo-length is greater 2!{/if}
      => foo-length is greater 2!

# Tags

In the Template Engine, tags are used either to output strings into the template, or to bracket blocks. Similar to HTML, tags take attributes, and usually they decide for themselves, how the content is parsed.

# Build-In Tags

# Text Output (Text)

text only knows the attribute source. The value of source is interpreted and inserted into the target document.

  • Example {text source="foo"}.
    In the following, we only use the short notation without source: {"foo"}. Both behave exactly the same.

If the result from source is null, an error is thrown. In ErrorMode WRITE_ERROR the string {ERROR(Null value.)} is output.

A string is taken one-to-one. Functions, calculations etc. are executed beforehand. The result of all applies.

  • Example: {"foo".toUpperCase()} outputs the string FOO.

Numbers are always output with .0. Other formats can be converted with function format.

  • Example: {6*6} outputs the string 36.0.

Type date is output in format ISO 8601 (opens new window). Other formats can be converted with the function format. #

  • Example: {getDate()} outputs the string 2017-09-19T13:08:20.743Z.

Boolean values (Boolean) are converted into a string:. true => true and false => false.

# If Statement (if)

The if statement can be used to check boolean expressions. For this purpose, the expressions is written with a space directly after the if.

If the expression is true, the if content is executed. Within, regular template blocks can be used. The block must be closed with {/if}.

Syntax: {if <Expression>}<Template>{/if}

  • Example:
    {if true}Content{/if}
    {if foo == "okay"}{bar}{/if}
    

If the expression is false, the contents of the else block (if available) is executed. else separates the if block into two areas and is placed in the if block.

Syntax: {if <Expression>}<Template>{else}<Template>{/if}

  • Example:
    {if false}if false{else}if true{/if}
    {if foo == 7}seven{else}{bar}{/if}
    

To check further expressions with else, use elseif. The content of elseif is only executed if the previous if is false and your own expression is true. Any number of elseif tags can be used in a row.

Syntax: {if <Expression>}<Template>{elseif <Expression>}<Template>{/if}

  • Example:
    {if false}first text{elseif true}second text{/if}
    {if foo == 7}seven{elseif foo == 9}nine{elseif foo == bar}{bar}{/if}
    

# Loop (loop)

With loop, an array can be run through. For this, the loop array must be assigned to attribute source. The array is then run from the beginning to the end. Within the loop block, the following variables are available:

Name Description
i sequence number, increments one with each iteration, starts at 0
_max Specifies the length of the array (corresponds the length function)
_entry The value of the current element of the iteration
$ lists the values of the above variables: {i=0, _max=3, _entry=1.0}

Syntax: {loop source=<Wert>}<Template>{/loop}

  • Example:
    Assuming 'foo' is an array ["a", "b", "c"]
    
    {loop source=foo}{foo[i]}{/loop} returns 'abc'
    {loop source=foo}{_entry}{if i < _max - 1},{/if}{/loop} returns 'a,b,c'
    

Within loop, the context is created by each _entry. If _entry is a map, variables can be accessed directly.

  • Example:
    Assuming 'foo' is an array [{"a": "one", "b": "two"}, {...}]
    
    {loop source=foo}{a};{b}{/loop} returns 'one;two'
    

# Build-in Functions

# length

length returns the length of a string, the number of array entries, or the number of Map entries.

Syntax: object.length()

  • Example:

    Assuming 'foo' has assigned value 'foobarbar'.
    {foo.length()} returns '9'
    
    Assuming 'foo' is an array with the values: "a", "b", "c" and "d".
    {foo.length()} returns '4'
    

# indexOf

Returns the index within the string of the first occurrence of the specified substring.

Syntax: object.indexOf(searchString)

Name Type Optional Default Description
searchString string No No The string to search for
  • Example:

    Assuming 'foo' has assigned value 'foobarbar'.
    {foo.indexOf("bar")} returns '3'
    {foo.indexOf("foo")} returns '0'
    

# lastIndexOf

Returns the index within the string of the last occurrence of the specified substring.

Syntax: object.lastIndexOf(searchString)

Name Type Optional Default Description
searchString string No No The string to search for
  • Example:

    Assuming 'foo' has assigned value 'foobarbar'.
    {foo.lastIndexOf("bar")} returns '6'
    {foo.lastIndexOf("foo")} returns '0'
    

# contains

contains can be executed on strings, arrays and maps.

# Strings

strings determines whether a character string within another string was found and returns true or false accordingly.

Syntax: stringVar.contains(searchString)

Name Type Optional Default Description
searchString string No None A string to be searched for within another string.

# Array

array determines whether an object was found within the array and returns true or false accordingly.

Syntax: arrayVar.contains(searchObject)

Name Type Optional Default Description
searchObject any No None An object to be searched for within the array.

# Map

map determines whether an object was found within the map and returns true or false accordingly. You can specify whether to search in the key or in the value.

Syntax: mapVar.contains(searchObject, where)

Name Type Optional Default Description
searchString string No None A string that defines either the "key" or "value" of the map being searched for.
where string yes value Specify whether the map should be searched for the key or the value. Possible values: key, value
  • Example:

    Assuming 'foo' has the value 'bar', and 'bar' has the value 'foo':
    {foo.contains("bar")} returns 'true'
    {bar.contains(foo)} returns 'false'
    
    Assuming 'foo' is an array: {"aa", "ab", "ac"}
    {foo.contains("a")} returns 'false'.
    {foo.contains("aa")} returns 'true'
    
    Assuming 'foo' is a map: {a: "aa", b: "ab", c: "ac"}
    {foo.contains("aa")} returns 'true'
    {foo.contains("b", "key") returns 'true'
    

# charAt

charAt returns the character of the position in the string that was specified in the parameter.

Syntax: object.charAt(position)

Name Type Optional Default Description
position numeric No None position in the string to be returned.
  • Example:

    Assuming 'foo' has assigned value 'foobar':
    {foo.charAt(4)} returns 'a'. (The index starts at 0)
    

# substring

substring extracts the characters from a string that lie between two indices and returns them as a new string.

Syntax: object.substring(start, end)

Name Type Optional Default Description
start numeric No None The position where the extraction should start. The index starts at 0.
end numeric Yes None The position (up to, but not including) where the extraction should end. If omitted, it extracts the entire rest of the string.
  • Example:

    Assuming 'foo' has assigned value 'foo,bar'
    {foo.substring(0, 3)} returns 'foo'
    {foo.substring(3)} returns 'bar'
    {foo.substring(4, 99)} returns 'bar'
    

right returns a string that matches the specified number of characters from the right side of the string. If the specified number of characters is longer than the length of the string, the entire string is returned.

Syntax: object.right(length)

Name Type Optional Default Description
length numeric No None Specifies how many characters from the right should be returned
  • Example:

    Assuming 'foo' has assigned value 'foobarbar'.
    {foo.right(3)} returns 'bar'
    {foo.right(30)} returns 'foobarbar'
    

# left

left returns a string that matches the specified number of characters from the left side of the string. If the specified number of characters is longer than the length of the string, the entire string is returned.

Syntax: object.left(length)

Name Type Optional Default Description
length numeric No None Specifies how many characters from the left should be returned
  • Example:

    Assuming 'foo' has assigned value 'foobarbar'.
    {foo.left(3)} returns 'foo'
    {foo.left(30)} returns 'foobarbar'
    

# concat

concat concatenates two strings. First, values from other types are tried to convert.

Syntax: object.concat(argument)

Name Type Optional Default Description
argument any No No argument to be appended as a string
  • Example:

    Assuming 'foo' has value 'bar', and 'bar' has value 'foo':
    {foo.concat(bar)} returns 'barfoo'
    

# replaceAll

replaceAll replaces all defined and found strings within a string with a specified new string of characters.

Syntax: object.replaceAll(searchString, replacement)

Name Type Optional Default Description
searchString string No None string to be searched for
replacement string No none new string to be inserted at the location where it is found
  • Example:

    Assuming 'foo' has assigned value 'foofoobarfoo'.
    {foo.replaceAll("foo", "bar")} returns 'barbarbarbar'
    

# replaceFirst

replaceFirst replaces only the first defined and found string within a string with a specified new string of characters.

Syntax: object.replaceFirst(searchString, replacement)

Name Type Optional Default Description
searchString string No None string to be searched for
replacement string No No string to be inserted at the location where it is found
  • Example:

    Assuming 'foo' has assigned value 'foofoobarfoo'.
    {foo.replaceFirst("foo", "bar")} returns 'barfoobarfoo'
    

# regexMatches

regexMatches returns whether the specified regex was matched successfully with a string.

Syntax: object.regexMatches(regexString)

Name Type Optional Default Description
regexString string No None regex to match
  • Example:

    Assuming 'foo' has assigned value 'foobarbar'.
    {foo.regexMatches(".*")} returns 'true'
    {foo.regexMatches("^f.*a?$")} returns 'true'
    {foo.regexMatches("1-9") returns 'false'
    

# regexReplace

regexReplace replaces all places in the string where the specified regex was matched successfully with the string.

Syntax: object.regexReplace(regexString, replacement)

Name Type Optional Default Description
regexString string No None regex to match
replacement string No None string to be inserted at the location where it is found
  • Example:

    Assuming 'foo' has assigned value 'foofoobarfoo'.
    {foo.regexReplace("^.*$", "bar")} returns 'bar'
    {foo.regexReplace("[ab]", "bar")} returns 'foofoobarrfoo'
    {foo.regexReplace("[0-9]", "bar")} returns 'foofoobarfoo'
    

# split

split splits the string where it matches the specified regex. Returns an array with separated elements.

Syntax: object.split(regexString)

Name Type Optional Default Description
regexString string No None regex to match
  • Example:

    Assuming 'foo' has assigned value 'foo,bar'
    {foo.split(",")[0]} returns foo
    
    Assuming 'foo' has assigned value 'foofoobarfoo'.
    {loop source=foo.split("f|b")}{_entry},{/loop} returns ',oo,oo,ar,oo,'
    

# toUpperCase

toUpperCase converts a string to uppercase letters only.

Syntax: object.toUpperCase()

  • Example:

    Assuming 'foo' has value 'FooBar':
    {foo.toUpperCase()} returns 'FOOBAR'.
    

# toLowerCase

toLowerCase converts a string to lowercase letters only.

Syntax: object.toLowerCase()

  • Example:

    Assuming 'foo' has value 'FooBar':
    {foo.toLowerCase()} returns 'foobar'.
    

# format

format returns a formatted string with the specified format and the object.

Syntax: object.format(formatString)

Name Type Optional Default Description
formatString string No None format string for formatting.
Oracle documentation: formatString (opens new window).
For data (date), the SimpleDateFormat is used: SimpleDateFormat (opens new window)
  • Example:

    Assuming 'foo' has value '3.14159265359':
    {foo.format("%.2f")} returns '3.14'
    {foo.format("%.2f").replaceAll(",", ".")} returns '3.14'
    {foo.format("%.0f")} returns '3'
    
    Assuming 'foo' has the value '223.45654543434'
    {foo.format("%6.3e")} returns '2.235e+02'
    {foo.format("%06.0f")} returns '000223'
    
    Assuming 'foo' is the date of '13:09:2017 14:14:53.769'
    {foo.format("yyyy")} returns '2017'
    {foo.format("hh:mm a")} returns '02:14 PM'
    {foo.format("dd.MM.yyyy kk:mm:ss")} returns '13.09.2017 14:14:53'
    

# toFileSize

toFileSize formats a number as file size. Both decimal (for the use of decimal prefixes) and binary (for the use of the binary prefix) can be specified (example: 4512 bytes => Binary: 4.4 KiB; Decimal: 4.5 KB).

Syntax: object.toFileSize(format)

Name Type Optional Default Description
format string No decimal Parameter to specify calculation. Possible values: binary, decimal.
  • Example:

    Assuming 'foo' has assigned value '4512'
    {foo.toFileSize()} returns '4,5 KB'
    {foo.toFileSize('decimal')} returns '4,5 KB'
    {foo.toFileSize('binary')} returns '4.4 KiB'
    

# trim

trim removes spaces at the beginning and the end of a string.

Syntax: object.trim()

  • Example:

    Assuming 'foo' has assigned value ' foo barbar '.
    {foo.trim()} returns 'foo barbar'
    

# lTrim

lTrim removes spaces only at the beginning of a string.

Syntax: object.lTrim()

  • Example:

    Assuming 'foo' has assigned value ' foo barbar '.
    {foo.lTrim()} returns 'foo barbar '.
    

# rTrim

rTrim removes spaces only at the end of a string.

Syntax: object.rTrim()

  • Example:

    Assuming 'foo' has assigned value ' foo barbar '.
    {foo.rTrim()} returns ' foo barbar'.
    

# compress

compress shortens a string to the specified length by deleting characters from the middle. Additionally, truncate characters are inserted to indicate the compression.

Syntax: object.compress(maxLength, truncateWith)

Name Type Optional Default Description
maxLength numeric No None Length to which the string is to be shortened, if necessary.
truncateWith string Yes ... String to be inserted in the middle (if truncated).
  • Example:

    Assuming 'foo' has assigned value 'foobarfoobar':
    {foo.compress(7)} returns 'foo...bar'. The string was shortened to 7 characters.
    

# getDate

getDate returns a date based on defined parameters. There are several possibilities to pass time and data:

  • As a number, you can specify the number of milliseconds since January, 1st 1970 00:00:00 GMT.
  • As a string, first format ISO 8601 (opens new window) ist tried to parse. If this does not work, the following format is attempted: yyyy/MM/dd HH:mm:ss.
  • Alternatively, the format can also be passed as additional parameter format (formatting as string details).

Note that if no parameter is passed, the current date is returned.

Syntax: getDate(date) or getDate()

Name Type Optional Default Description
date numeric
string
Yes None Specifies the date as a string or number to be converted to a date.
format string Yes None Specifies the format in which the date parameter is passed.
  • Example:

    {getDate()} returns the current date. For example '2024-09-13T15:04:11.588Z'
    {getDate(1500000000000)} returns '2017-07-14T02:40:00.000Z'
    {getDate("2017-07-14T04:40:00.000Z")}
    

# toDateString

toDateString formats a given Date object into a human-readable string using the specified format and an optional time zone.

This function is especially useful for transforming dates into specific patterns or for adapting the output to different locales or display requirements. The format follows the Java DateTimeFormatter (opens new window) patterns. If a time zone is provided, the output will reflect the corresponding local time.

Syntax: {date.toDateString(format, zoneId)}

Name Type Optional Default Description
format string No The format used to render the date as a string. Must follow Java formatting rules.
zoneId string Yes UTC Apply the IANA time zone ID (e.g. Europe/Berlin, America/New_York) for formatting.

Example:

{myDate.toDateString('yyyy-MM-dd')} returns '2024-05-21'
{myDate.toDateString('HH:mm:ss', 'Europe/Berlin')} returns '17:21:00'
{myDate.toDateString('yyyy-MM-dd HH:mm:ss', 'America/New_York')} returns '2024-05-21 11:21:00'

Notes:

  • If zoneId is omitted, UTC is used by default.
  • The values from the value option user_time_zone in the user module are also supported for the zoneId parameter.
    • Example: {myDate.toDateString("dd.MM.yyyy", time_zone)} in the user module (using the value option behind the metadata field time_zone)
  • Invalid or unrecognized zone IDs will result in an error.
  • This function only works on objects of type Date. You can create a Date object using getDate(...).

# asTimezone

asTimezone shifts a given Date object from UTC into the local time of the specified time zone. The result is still a Date object (which is always UTC under the hood), but the value represents the same local timestamp as if the date had been originally created in that target time zone.

This function is useful when a UTC-based Date needs to be reinterpreted in the context of another time zone before further processing or formatting.

Syntax: {date.asTimezone(zoneId)}

Name Type Optional Default Description
zoneId string No The IANA time zone ID (e.g. Europe/Berlin, America/New_York) determines how to reinterpret the date.

Example:

{datefield.asTimezone("Europe/London")}
{datefield.asTimezone("UTC")}
{getDate().asTimezone("UTC")}

Notes:

  • The returned object is still a Date, not a formatted string.
  • This function does not change the actual instant in time, but rather shifts the date so that the local time in the specified zone is preserved.
  • The values from the value option user_time_zone in the user module are also supported for the zoneId parameter.
    • Example: {myDate.asTimezone(time_zone)} in the user module (using the value option behind the metadata field time_zone)
  • Invalid or unrecognized zone IDs will result in an error.
  • This function only works on objects of type Date. You can create a Date object using getDate(...).

# addDuration

addDuration adds a specific amount of time to a given Date object. The amount and unit of the time to add are passed as arguments. The function returns a new Date object with the adjusted time.

This function is useful for time calculations such as "5 days later", "2 hours ahead", or "10 seconds after a specific timestamp".

Syntax: {date.addDuration(amount, unit)}

Name Type Optional Default Description
amount number No The number of time units to add. Can be positive or negative.
unit string Yes "T" The time unit to apply. If omitted or blank it defaults to milliseconds ("T").

Supported units:

Unit Description
"u" Microseconds
"T" Milliseconds
"s" Seconds
"m" Minutes
"h" Hours
"d" Days
"w" Weeks
"M" Months
"y" Years

Example:

{myDate.addDuration(5, "d")}   // Adds 5 days
{myDate.addDuration(-3, "h")}  // Subtracts 3 hours
{myDate.addDuration(1000)}     // Adds 1000 milliseconds (default unit)

Notes:

  • The returned object is a new Date object; the original is not modified.
  • This function only works on objects of type Date. If the input is not a Date, an error is thrown.
  • If the unit is not one of the supported values, an error is thrown.

# md5

md5 returns the MD5 (opens new window) hash of a string as a hex encoded string.

Syntax: object.md5()

  • Example:

    Assuming 'foo' has assigned value 'foobarbar'.
    {foo.md5()} returns 'aa65a413921163458c52fea478d5d3ee'
    

# join

join combines the elements of a provided list into a single string. separator defines a character string to separate the elements.

Syntax: list.join(separator) or list.join()

Name Type Optional Default Description
separator string yes blank separator to separate the list's elements. null or no value is treated as an empty string.
  • Example:

    Assuming 'foo' is a list of the following elements: ['elem1', 'elem2']
    {foo.join()} returns 'elem1elem2'
    {foo.join(", ") returns 'elem1, elem2'
    

# toArray

toArray builds a list from all arguments.

Syntax: toArray(arg1, arg2, arg3, ...)

  • Example:

    {toArray("a", "b", "c").join(", ") returns 'a, b, c'
    

# sort

sort sorts the elements of a provided list. order specifies the sorting direction: ascending (asc) or descending (desc).

Syntax: list.sort(order) or list.sort()

Name Type Optional Default Description
order string yes blank sorting direction to arrange the elements. null or no value is treated as an ascending sort.
  • Example:

    Assuming 'foo' is a list of the following elements: ['B', 'C', 'A']
    {foo.sort().join(", ")} returns 'A, B, C'
    {foo.sort("desc").join(", ") returns 'C, B, A'
    

# filter

filter returns only the elements matching the defined filter's criteria.

Syntax: object.filter(operator, filter)

Name Type Optional Default Description
operator string no none filter Operator. Currently only in is supported.
filter object no none filter criteria define what elements to filter for.
For operator in it's a string list.
  • Example:

    Assuming 'foo' is a list of the following elements: ['a', 'b', 'c']
    {foo.filter('in', toArray('b', 'c')).length()} returns '2'
    {foo.filter('in', toArray('b', 'c')).join(', ')} returns 'b, c'
    

# Appendix

# Ranking of Operators

Weighting Operators
2 &#124;&#124;
3 &&(&amp;&amp;)
7 < (&lt;), > (&gt;), <=(&lt;=), >= (&gt;=) ==, !=
10 +, -
20 *, /
30 !, - (prefix)
40 ., [], () (function call)

# Cheat Sheets

Loops:

{loop source=myList}
  {_entry},{i},{_max},{$}
  {if i < _max - 1};{/if}
{/loop}

Logic:

{if foo == bar}
  Content
{elseif foo == bar}
  Content
{else}
  Content
{/if}

Arithmetic:

{4 * 4.5} {(40 + 30) / 10}

Number format:

{(12/7).format("%.0f")} => 2
{(12/7).format("%.2f")} => 1,71

String:

  • length()
  • indexOf(str) / lastIndexOf(str)
  • contains(str) / regexMatches(reg_str)
  • charAt(num)
  • substring(num, num) / left(num) / right(num)
  • concat(str)
  • replaceAll(str, str) / replaceFirst(str, str) / regexReplace(reg_str, str)
  • split(reg_str)
  • toUpperCase() / toLowerCase()
  • format(str)
  • trim() / lTrim() / rTrim()
  • compress(num, str)

Numbers:

  • toFileSize("decimal" or "binary")
  • format(str)

Lists:

  • length()
  • contains(obj)

Maps:

  • length()
  • contains(obj, "key" or "value")

Other:

  • getDate()
  • md5(str)
Request missing documentation