The engine uses syntax that is similar to Liquid or Mustache, but while looking alike, they are totally different. That's because this template engine uses a lisp-like language for templates. This allows the parser to accept adding custom C and C++ functions.
By default, we ship with a standard library containing basic functionality, that most projects will use close to 100% of the time.
Type system
Before we begin with the actual guide, we need to explain the type system of the templating engine. Our custom language is weakly-typed and uses strings to represent all values.
We also support 4 type hints:
- Normal - A regular string
- Function - The string contains code that can be passed to the
parser. Commonly, this is used for function bodies of functions like
for
andif
- Array - The string needs to be treated as an array
- Map - The string needs to be treated as a map
Functions and variables
The syntax for calling a function is the following:
{{ my-function arg1 arg2 arg3 ... argn }}
Variables are also functions, which means that to get the value of a variable, you simply need to call it like a function:
{{ my-variable }}
Arrays and maps
Accessing using the
at
function
You can access an array at an index using the following call:
{{ at {{ my-array }} 0 }}
A map can be accessed by replacing the numeric index with a string:
{{ at {{ my-map }} my-key }}
Iterating using the
for
function
You can iterate an array like this:
{{ for it {{ my-array }} {{ func This is {{ it }}
}} }}
Its arguments are like this:
- Name of the iterator variable
- The array data. If not forwarded by a variable function call, it will iterate the string
- A function representing the body of the function - Inside the body you can reference the iterator variables
You can iterate a map like this:
{{ for key val {{ my-map }} {{ func Key: {{ key }}
Value: {{ val }}
}} }}
Its arguments are like this:
- Name for the key iterator variable
- Name for the value iterator variable
- The array data. If not forwarded by a variable function call, the parser will return an error
- A function representing the body of the function - Inside the body you can reference the iterator variables
The list
function
The list
function takes a variadic list of arguments and
converts it into an array variable that can be forwarded to any function
that requires an array argument. It is used like this:
{{ list A B C D E F }}
The dict
function
The dict
function takes a variadic list of arguments and
converts it into a map variable that can be forwarded to any function
that requires a map argument. It is used like this:
{{ dict A B C D E F }}
Each odd element(counting from 1) of the variadic arguments list is used as the key, while each even element is used as the value.
Note
If the function call has an odd number of arguments i.e. the last argument is a new key, not a new value, the key will be created with an empty value.
The raw
function
The raw
function constructs a raw string, which is not
parsed. It is used like this:
{{ raw {{ for a {{ arr }}
{{ func
{{ a }}
}}
}} }}
This will return the following string:
{{ for a {{ arr }}
{{ func
{{ a }}
}}
}}
The comment
function
You can use the comment
function to write comments in
the file template, without them being saved to the final template. It is
used like this:
{{ comment This is a comment and will only be here in the template }}
The func
function
The func
function returns a raw string with no
formatting from its arguments and marks it with the function hint. This
allows other functions to use it as a callback function by passing its
string data to a parser instance. It is used like this:
{{ my-func {{ func This raw string will be passed to "my-func". Call number: {{ my-func-call-num }} }} }}
As you can see, we call {{ my-func-call-num }}
. As
functions can add additional variables and functions to the parser,
functions that accept functions can utilise this to enable the function
callback to have access to certain values.
Boolean operators
The following functions implement boolean iterator constructs:
==
- Checks if all values of the variadic arguments list of the function are equal!=
- Checks if all values of the variadic arguments list of the function are not equal&&
- Returns the value of a boolean AND operation done on all arguments, part of the variadic arguments list of the function||
- Returns the value of a boolean OR operation done on all arguments, part of the variadic arguments list of the function!
- Given a single argument with a boolean value, returns its boolean NOT value
Branches
The if
function
The if
functions is different compared to most
if
statements in modern programming languages. It's more
like the ternary
operator, without the possibility of assigning a variable to the
result. It looks like this:
{{ if {{ == {{ value }} test }}
{{ func {{ test_val }} }}
{{ func {{ not_test_val }} }}
}}
The arguments are like this:
- A boolean expression
- A function that will be called if the previous argument is set to true
- A function that will be called if the previous argument is set to false
The switch
function
Additionally, the switch
function can be used as a
switch statement in high level languages like JavaScript. The syntax
looks like this:
{{ switch {{ value }}
test {{ func {{ test_val}} }}
example {{ func {{ example_val }} }}
{{ func {{ fallback_val }} }}
}}
The arguments are like this:
- Value to match
- A variadic arguments list. Arguments should be ordered so that each argument with an odd index(starting from 1) corresponds to a value, and each with an even corresponds to a function. The only exception is the last argument, which may be a function.
- The last argument is the fallback function.
Note
If the switch function is called with such arguments, that the last argument is a function that is also used to match a value, the fallback function is set to the default fallback function, which returns an empty string
The cond
function
Finally, the cond
function can be used as a replacement
of the if
statement in modern programming languages. It
looks like this:
{{ cond
{{ == {{ value }} test }}{{ func {{ test_val }} }}
{{ == {{ value }} example }}{{ func {{ example_val }} }}
{{ func {{ fallback_val }} }}
}}
The function takes a variadic list of arguments, where each odd index(counting from 1) corresponds to a boolean expression and each even index corresponds to a function. The only exception to this is the final argument, which should always be a function. It will be called if all other conditions fail.
Note
If the fallback function is not set, the default fallback function will be called. It returns an empty string.
Important notes
The following special functions differ in parsing behaviour:
func
raw
comment
The differences are these:
- Trailing whitespace or separator characters are not removed from the
last argument, so for example
{{ func A B C D E }}
will produce the stringA B C D E
- There always needs to be a whitespace or separator character between
the function name and the beginning of the raw string. This invalidates
expressions like these:
{{ func{{ my_var }}}}
. Instead, a whitespace should always be added, like this:{{ func {{my_var}}}}