# 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 placeholder can be set. These wildcards are used during the generation of by correct values, which are also passed to the Template Engine must be replaced. For example, Hello {name}! is replaced by Generation 'Hello Hans Meier'. Besides simple variables you can also use queries, loops and functions are processed.

The Template Engine's so-called "HTML engine" can be used with all types of work from texts. So can, to name a few, HTML, text, XML, TeX, CSV or JSON files are processed. Furthermore, a "XLSX Engine" included. It allows the definition of templates with Excel. The output can be converted to 'xlsx', 'csv' and also other formats are made. Besides Excel, there is also the "DOCX Engine". You allows the definition of templates with Word. It can use .docx as well as output .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 also. The decimal separator must always be the dot (.) can be used.

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. There are two types of declaration made possible. Both behaviors are completely identical. It will only UTF-8 character encoding supported.

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

Within double quotes("), single quotes(') can be used by using and within single double.

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 used as a variable are passed by the implementation or can be implemented by functions such as Example getDate is created.

Example: {getDate()}

# Lists (Array)

A list can contain several elements of other types, but also other lists contained. Lists can only be passed from the environment. There are no possibility to create a new list at runtime of the TemplateEngine define. Lists start at 0, so the first element is defined with 0 accessed.

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

Example: {myList.length()}

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

Example: {myList[5]}

Lists can be run through with the tag loop will be.

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 created by the environment be handed over. There is no option at runtime of the TemplateEngine to define a new map.

The length of a map can be queried with the function length will be.

Example: {myMap.length()}

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

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

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

ExampleL: {myMap.contains("element1")}

# Functions

Functions are executable logics that are used by the Template Engine have been deposited. Usually they load data or change the values of variables. Functions can take values (here parameters), that change behavior.

Syntax: {[variable.]funktionsname([parameter[, parameter]])}

Examples:

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

There are a number of [Build-In functions](#build-in functions). Additionally, custom functions can be added via plugins or overwrite existing ones and thus extend or even change them.

# Arithmetic

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

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.

Operators

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 in order to For example, in a If statement (if). The return value of one of these operators is therefore always a Truth value (Boolean).

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> kleiner < Syntax: <Operand><<Operand> Returns 'true' if the left operator is "greater" or "less" than the right operator. Only numbers are supported.
greater or equal >= Syntax: <Operand>>=<Operand> kleiner oder gleich <= Syntax: <Operand><=<Operand> Returns 'true' if the left operator is "greater" or "less" than or equal to the right operator. Only numbers are supported. Alternatively, &gt;=' and<=' 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 \|\| Syntax: <Operand>\|\|<Operand> Returns false' if either the left, the right, or both operators aretrue'. 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.

Boolean operators

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

Tags are used in the Template Engine either to output strings in the template, or used to bracket blocks. Take Tags attributes are missed, similar to HTML, usually the tags themselves, however, how their content is "parsed".

# Build-In Tags

# Text output (text)

text only knows the attribute source. The value of source is is interpreted and inserted into the target document. Example {text source="foo"}. In the following, however, only the short notation without source'' used:foo''. Both behave exactly the same.

If the result from source is zero, an error is thrown. In ErrorMode 'WRITE_ERROR' the string `{ERROR(Null value.)}' is output. For the further ErrorModes see ErrorMode

A string is taken 1 to 1. Functions, Calculations etc. are of course executed beforehand. The following is then taken over Result of this.## Tags

Tags are used in the Template Engine either to output strings in the template, or used to bracket blocks. Take Tags attributes are missed, similar to HTML, usually the tags themselves, however, how their content is "parsed".

# Build-In Tags

# Text output (text)

text only knows the attribute source. The value of source is is interpreted and inserted into the target document. Example {text source="foo"}. In the following, however, only the short notation without source'' used:foo''. Both behave exactly the same.

If the result from source is zero, an error is thrown. In ErrorMode 'WRITE_ERROR' the string `{ERROR(Null value.)}' is output. For the further ErrorModes see ErrorMode

A string is taken 1 to 1. Functions, Calculations etc. are of course executed beforehand. The following is then taken over Result of this.

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

numbers are always output with '0'. Other formats can be converted with of the function format can be converted.

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

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

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

Boolean values (Boolean) are converted into String converted. true => true and false => false.

# If statement (if)

The If statement can be used to check Boolean expressions. For this purpose the printout is printed with a space directly after the if. If the expression is true, the content is executed by the 'iF'. In this content you can also use whole normal template blocks can be used. The block must be terminated with {/if}. can be closed.

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

{if true}Inhalt{/if}
{if foo == "okay"}{bar}{/if}

If the expression is false, if any, then the expressions of the Contents of the 'else' block executed. else separates the `if' block into two areas and is placed in the 'iF' block.

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

{if false}Wenn wahr{else}Wenn falsch{/if}
{if foo == 7}Sieben{else}{bar}{/if}

If one would like to check further expressions with the 'else', then ‚elseif' is the best choice on. The content of 'elseif' is only executed if the previous `if' is false and your own expression is true. You can use any many 'elseif' tags are used one after the other.

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

{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 the 'loop' an array can be passed through. To do this, the `loop' array must be be assigned to the attribute 'source'. The array is then called from the beginning run through 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 to 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}

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. Is _entry i.e. a map, variables can be accessed directly.

Assuming 'foo' is an array [{"a": "one", "b": "two"}, {...}]

{loop source=foo}{a};{b}{/loop} returns one;two

# Build-in functions

# length

Returns the length of a **string **, the number of entries of an Array or the number of entries of a Map.

Syntax: object.length()

Example:

Assume that 'foo' has assigned the 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

Parameters

Example:

Assume that 'foo' has assigned the 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

Parameters

Example:

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

# contains

contains can be executed on strings, arrays and maps.

String: 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 No A string to be searched within the other string.

Parameter

Array: Determines whether an object was found within the array and returns 'true' or 'false'.

Syntax: arrayVar.contains(searchObject)

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

Parameter

Map: Determines whether an object was found within the map and returns 'true' or 'false' accordingly. You can also use specified whether the search is to be carried out 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 |

Parameter

Example:

Assume 'foo' has the value "bar" and 'bar' has the value "foo":
{foo.contains("bar")} returns `true`
{bar.contains(foo)} returns `false

Suppose '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

Returns the character which is to be found at the position specified in the parameter in of the string is back.

Syntax: object.charAt(position)

Name Type Optional Default Description
position numeric No No position in the string to be returned.

Parameter

Example:

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

# substring

Extracts the characters from a string that lies between two and returns them as a new string.

Syntax: object.substring(start, end)

| Name | Type | Optional | Default | Description |

| start | numeric | No | No | The position where the extraction should start. The index starts at 0. | | end | numeric | Yes | No | The position (up to, but not including) at which the extraction should end. If omitted, it extracts the entire rest of the string. |

Parameter

Example:

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

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

Syntax: object.right(length)

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

Parameter

Example:

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

# left

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

Syntax: object.left(length)

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

Parameter

Example:

Assume that 'foo' has assigned the value 'foobarbar'.
{foo.left(3)} returns foo
{foo.left(30)} returns foobarbar

# concat

Hangs two strings together. An attempt is first made both Convert values from other types to convert.

Syntax: object.concat(argument)

Name Type Optional Default Description
argument any No No argument to be appended as string

Parameter

Example:

Assume 'foo' has the value "bar" and 'bar' has the value "foo":
{foo.concat(bar)} returns `barfoo

# replaceAll

Replaces all places in the string where the specified string was found, with the specified string.

Syntax: object.replaceAll(searchString, replacement)

Name Type Optional Default Description
searchString string No None String to be searched.
replacement string No none string to be inserted at the location where it is found

Parameters

Example:

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

# replaceFirst

Replaces the first position in the string where the specified string was found, with the specified string.

Syntax: object.replaceFirst(searchString, replacement)

Name Type Optional Default Description
searchString string No None String to be searched.
replacement string No No string to be inserted at the location where it is found.

Parameters

Example:

Assume that 'foo' has assigned the value 'foofoobarfoo'.
{foo.replaceFirst("foo", "bar")} get barfoobarfoo

# regexMatches

Returns whether the specified regex with the string successfully could be synchronized.

Syntax: object.regexMatches(regexString)

Name Type Optional Default Description
regexString string No No The regex to match

Parameter

Example:

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

# regexReplace

Replaces all places in the string where the specified regex could be compared with the specified string.

Syntax: object.regexReplace(regexString, replacement)

Name Type Optional Default Description
regexString string No No The regex to match
replacement string No None String to be inserted at the location where it is found.

Parameter

Example:

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

# split

Splits the string into matches of the specified Regex. Returns an array with the shared elements.

Syntax: object.split(regexString)

Name Type Optional Default Description
regexString string No No The regex to match

Parameter

Example:

Assuming 'foo' has assigned the value 'foo,bar
{foo.split(",")[0]} returns foo

Assume that 'foo' has assigned the value 'foofoobarfoo'.
{loop source=foo.split("f|b")}{_entry},{/loop} returns ,oo,oo,ar,oo,

# toUpperCase

Converts a string to uppercase letters only.

Syntax: object.toUpperCase()

Example:

Assume that 'foo' has the value 'FooBar':
{foo.toUpperCase()} returns 'FOOBAR'.

# toLowerCase

Converts a string to lowercase letters only.

Syntax: object.toLowerCase()

Example:

Assume that 'foo' has the value 'FooBar':
{foo.toLowerCase()} returns 'foobar'.

# format

Returns a formatted string with the specified format and Object back.

Syntax: object.format(formatString)

Name Type Optional Default Description
formatString string No No format string for formatting. Oracle documentation: formatString (opens new window). The SimpleDateFormat is used for data (date): SimpleDateFormat (opens new window)

Parameter

Example:

Assuming 'foo' has the value 3.14159265359:
{foo.format("%.2f")} returns 3.14
{foo.format("%.2f").replaceAll(",", ".")} returns 3.14
{foo.format("%.0f")} get 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

Formats a number as file size. It can be decimal for the use of decimal prefixes or binary for 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 Beschreibung
format string Nein decimal Parameter zur Spezifikation der Berechnung. Mögliche Werte: binary, decimal.

Parameter

Example:

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

# trim

Removes spaces at the beginning and end of the string.

Syntax: object.trim()

Example:

Assume that 'foo' has assigned the value ' foo barbar '.
{foo.trim()} returns 'foo barbar

# lTrim

Removes spaces at the beginning of the string.

Syntax: object.lTrim()

Example:

Assume that 'foo' has assigned the value ' foo barbar'.
{foo.lTrim()} returns 'foo barbar'.

# rTrim

Removes spaces at the end of the string.

Syntax: object.lTrim()

Example:

Assume that 'foo' has assigned the value ' foo barbar'.
{foo.lTrim()} returns 'foo barbar'.

# compress

Shortens the given string to the specified length. In doing so in the exact middle of the page, characters are inserted to indicate that has been cut.

Syntax: object.compress(maxLength, truncateWith)

| Name | Type | Optional | Default | Description | | ------------ | ------- | -------- | ------- | ———————————————————————————————————————— | | maxLength | numeric | No | None | Length to the length the string should be shortened if necessary | | truncateWith | string | Yes | ... | The string to be inserted in the middle if truncated. |

Parameter

Example:

Assume 'foo' has assigned the value "foobarfoobar":
{foo.compress(7)} returns `foo...bar`. This set the string to 7 
Sign shortened.

# getDate

Returns a date based on the parameters. If no parameter is passed, the current date is returned. There are several Possibilities to pass a time. As a number you can specify the number of milliseconds since 1 January 1970 00:00:00 GMT. A "String" is first tried into the ISO 8601 (opens new window) format to parse. If this does not work, the following format is attempted: yyyy/MM/dd HH:mm:ss. Alternatively, the format can be used as an additional parameter 'format' must be specified. For formatting as String see format.

Syntax: getDate(date) or getDate()

Name Type Optional Default Description
date numeric string Yes None
format string Yes None Specifies the format in which the 'date' parameter is passed.

Parameter

Example:

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

# md5

Returns the MD5 (opens new window) hash of character string returned as a hex encoded string.

Syntax: object.md5()

Assume that 'foo' has assigned the value 'foobarbar'.
{foo.md5()} returns aa65a413921163458c52fea478d5d3ee

# join

Combines the elements of the provided list into a single String containing the specified list of elements. The `separator'. specifies 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 elements. zero or no value is treated as an empty string.

Parameter

Example:

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

# toArray

Builds a list from all arguments

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

Example:

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

# sort

Sorts the elements of the provided list. The 'order' specifies a Sort direction, ascending (asc) or descending (desc).

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

Name Type Optional Default Description
order string yes blank sorting direction for the arrangement of the elements. 'zero' or no value is treated as an ascending sort.

Parameter

Example:

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

# filter

Filters only the elements matching the filter criterion

Syntax: object.filter(operator, filter)

Parameter
name Type optional Default description
operator string no no Filter Operator. Currently only in is supported

filter

object

No

No

Filtercretarium defines which data are selected.

for filter operator in a list of string.

Example:

Suppose '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

# Anhang

# Operator sequence

Weighting Operators
2 \|\|
3 &&, &amp;&amp;
7 <, >, <=, >=, ==, !=, &lt;, &gt;, &lt;=, &gt;=
10 +, -
20 *, /
30 !, - (Sign)
40 ., [], () (Function call)

# Cheat Sheet

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" oder "binary")
  • format(str)

Lists:

  • length()
  • contains(obj)

Maps:

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

Sonstige:

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