# 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'')
# 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
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, >=' 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, && can be used. |
or \|\| Syntax: <Operand>\|\|<Operand> | Returns false' 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 . |
Boolean operators
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
# right
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)
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 |
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 | && , && |
7 | < , > , <= , >= , == , != , < , > , <= , >= |
10 | + , - |
20 | * , / |
30 | ! , - (Sign) |
40 | . , [] , () (Function call) |
# Cheat Sheet
loops:
| Logic:
|
Arithmetic:
|
|
String:
| Numbers:
Lists:
Maps:
Sonstige:
|