Writing templates with Apache FreeMarker
The step following the execution of the query is the generation of the display. The language used to write templates in Elements Connect is Apache FreeMarker, version 2.3.31. It is a powerful templating language developed and maintained by Apache.
Practical examples
Depending on the field type - Select list (single choice or multiple choices) or Read only - the template does not work the same way. Read some practical examples on how to write templates in Elements Connect for Select list and Read only items.
Apache FreeMarker directives
Here is a (non-exhaustive) Apache FreeMarker reference manual
List
It is common to deal with lists in a template. The most frequent use case is the resultSet
variable in case of a multi values result set with a read only Connected item.
Official FreeMarker documentation pages related to lists:
You'll find below the most common functions and built-ins.
Iterate over a list
Iterate over a list named "sequence". Official documentation
In Elements Connect, the resultSet variable, available in the template of a "Text - Read only" Connected item using a database datasource is a list.
For "Text - Read only" Connected items using a REST API datasource, the data variable can be used.
<#list sequence as item>
<!-- Part repeated for each item -->
<#else>
<!-- Part executed when there are 0 items -->
</#list>
Filter a list
Built in to filter a list. Official documentation
<#assign xs = [1, -2, 3, 4, -5]>
Positives:
<#list xs?filter(x -> x > 0) as x>${x} </#list>
Negatives:
<#list xs?filter(x -> x < 0) as x>${x} </#list>
Output
Positives:
1 3 4
Negatives:
-2 -5
Sort a list
Built in to sort a list. Official documentation
<#assign ls = ["whale", "Barbara", "zeppelin", "aardvark", "beetroot"]?sort>
<#list ls as i>${i} </#list>
Output
aardvark Barbara beetroot whale zeppelin
String
In the developers' world, a String is used to store text. It is certainly the most common and most useful type on Earth. Read the official documentation and check the selection below.
contains
Returns if the substring specified as the parameter to this built-in occurs in the string.
<#if "Elements Connect"?contains("onne")>It contains "onne"</#if>
Output
It contains "onne"
length
Return the number of characters in a string.
${"Elements Connect"?length} chars
Output
16 chars
starts_with
Returns true
if the String contains the specified substring.
<#if "Elements Connect"?starts_with("El")>Starts with 'El'</#if>
Starts with 'El'
Numbers
We can do some things with numbers, like counting for example. Read the official documentation and check the selection below.
abs
Returns the absolute value of a number
{-42?abs} is the meaning of life
Output
42 is the meaning of life
string
Convert a number to a string and apply the formating. Official documentation.
<#assign x=42>
${x}
${x?string} <#-- the same as ${x} -->
${x?string.number}
${x?string.currency}
${x?string.percent}
${x?string.computer}
Output
42
42
42
$42.00
4,200%
42
Dates
After String and Number, Date is certainly the 3rd most popular data type. With date, we can store important information like birthdays, the start of holidays or payday. Read the official documentation and check the selection below.
Comparing dates
<#-- We assume date1 and date2 are date-time values -->
<#if date1 > date2>
date1 is after date2
<#else>
date1 is before date2
<#/if>
<#-- Compare to the current date -->
<#if date1 > .now?date>
date1 is in the future
<#else>
date1 is in the past
<#/if>
Conditions
if, else, elseif
"Life is like a box of chocolate you never know what you're going to get" the same goes for templates: sometimes it's green, sometimes it's red. Let's see how we can have conditions in our templates. Read the official documentation.
<#assign price = 66>
<#if (price > 100)>
Price is above 100
<#elseif (price >= 50)>
Price is between 50 and 100
<#else>
Price is below 50
</#if>
Output
Price is between 50 and 100
switch, case, default, break
The switch/case directives offer a more advanced control flow than the if / else. Official documentation.
<#switch animal.size>
<#case "small">
This will be processed if it is small
<#break>
<#case "medium">
This will be processed if it is medium
<#break>
<#case "large">
This will be processed if it is large
<#break>
<#default>
This will be processed if it is neither
</#switch
Check if a variable exists / is not empty
To check if the value exists:
<#if row.type??>
Type: ${row.type}
</#if>
To check if a value exists and is not empty:
<#if row.type?has_content>
Type: ${row.type}
</#if>
Variables
When dealing with complex structures, it can be helpful to store information in local variables. Here is how it can be done:
<!-- Assign the first element of a list to a variable -->
<#assign first = someList[0]>
<!-- Assign a string -->
<#assign color = "yellow">
<!-- Assign a sequence -->
<#assign seq = ["foo", "bar", "baz"]>