Velocity Reference
Our system features the dynamic content option using the Apache Velocity library. Let’s review the most common Velocity features to use in Reteno.
Quick reference for Velocity syntax in Reteno.
For practical examples, see Using Velocity in Messages and Using Velocity in Workflows.
Variable Formats
| Format | Description |
|---|---|
$discount | If the variable does not exist, outputs the literal text $discount |
$!discount | Silent — outputs nothing if the value is missing |
${discount} | Braces unambiguously delimit the variable name from adjacent text |
$!{discount} | Silent and unambiguous — recommended for production use |
${discount|$otherGift} | Outputs the fallback value if the variable is missing |
Nested Objects
Use dot notation to access fields inside an object:
$item.product$lastTraining.trainingDay$manager.phone
Arrays and Indexes
Access an element by index (0-based):
$!arrayName[0]$!items[0].parameterName
If the specified index does not exist, an error will occur at send time. Use a loop when the array size is not known in advance.
Get the array size:
$!arrayName.size()
Note The exact access path depends on the structure of the payload. Some events contain a plain array, while others wrap it inside an object.
Loops
Iterate over all elements in an array with #foreach:
#foreach($item in $!arrayName)
$foreach.count: $!item.name
#end
$foreach.count is the loop counter, starting from 1.
Stop the loop early with #break:
#foreach($item in $!arrayName)
$!item.name
#if($foreach.count > 5) #break #end
#end
In email HTML, wrap directives in comments: <!--#foreach(...)-->, <!--#end-->
Assignment
Assign a value to a variable for reuse within the template:
#set($var = 'value')
#set($total = $mathTool.add($price, $tax))
Conditions
Basic condition:
#if($!param == 'value')
content
#end
With alternative:
#if($!param == 'value')
content
#else
altContent
#end
Multiple conditions:
#if($!param == 'value1')
content1
#elseif($!param == 'value2')
content2
#else
altContent
#end
Check for non-empty value:
#if($!param && $!param != '')
content
#end
Operators
Comparison
| Operator | Meaning |
|---|---|
== | Equal |
!= | Not equal |
gt | Greater than |
lt | Less than |
ge | Greater than or equal |
le | Less than or equal |
Logical
| Operator | Meaning |
|---|---|
&& or and | Logical AND |
|| or or | Logical OR |
! or not | Logical NOT |
String comparison
$!firstString.equals($!secondString)$!firstString.equalsIgnoreCase($!secondString)
Arithmetic
$mathTool.add($v1, $v2)$mathTool.sub($v1, $v2)$mathTool.mul($v1, $v2)$mathTool.div($v1, $v2)
Number Formatting
Integer without rounding:
$numberTool.integer($v1)
Money amount with two decimal places:
$!numberTool.format('#.00', $v1)
Dates
Output
Current date:
$!dateTool.currentDate()$!dateTool.currentDate('dd.MM.yyyy HH:mm:ss', 'GMT+3')
Current Unix timestamp:
$!dateTool.currentTimeStamp()
Format a date from the event or contact field:
$!dateTool.formatDate('dd.MM.yyyy', $!date)$!dateTool.formatDate('yyyy-MM-dd HH:mm:ss', $!date)
Format in the contact's time zone:
$!dateTool.formatInContactTimezone('dd/MM/yyyy HH:mm:ss', $!dateTime)
Arithmetic
Given "date": "01/01/2020 12:00":
$!dateTool.addYears($!date, 2)→ 01/01/2022 12:00$!dateTool.addMonths($!date, 5)→ 01/06/2020 12:00$!dateTool.addDays($!date, 15)→ 16/01/2020 12:00$!dateTool.addHours($!date, 7)→ 01/01/2020 19:00$!dateTool.addMinutes($!date, 15)→ 01/01/2020 12:15
Negative values subtract:
$!dateTool.addDays($!date, -7)
With custom input format — given "customDate": "12:00 2020-30-04":
$!dateTool.addYears($!customDate, 2, 'HH:mm yyyy-dd-MM')→ 12:00 2022-30-04
With custom input and output format — given "dateTime": "2020-05-01T00:00":
$!dateTool.addDays($!dateTime, 2, "yyyy-MM-dd'T'HH:mm", 'dd-MM-yyyy')→ 03-05-2020$!dateTool.addHours($!dateTime, 7, "yyyy-MM-dd'T'HH:mm", 'dd/MM HH:mm')→ 01/05 07:00$!dateTool.addMinutes($!dateTime, 2, "yyyy-MM-dd'T'HH:mm", 'HH:mm')→ 00:02
Difference between two dates
Given "firstDate": "01/01/2019", "secondDate": "05/05/2020":
$!dateTool.diff($!firstDate, $!secondDate, 'YEARS')→ 1$!dateTool.diff($!firstDate, $!secondDate, 'MONTHS')→ 16$!dateTool.diff($!firstDate, $!secondDate, 'DAYS')→ 490$!dateTool.diff($!firstDate, $!secondDate, 'HOURS')→ 11760$!dateTool.diff($!firstDate, $!secondDate, 'MINUTES')→ 705600
With custom format — given "customDate1": "17:15 05/05/2020", "customDate2": "10:05 01/01/2019":
$!dateTool.diff($!customDate1, $!customDate2, 'HH:mm dd/MM/yyyy', 'MINUTES')→ 706030
Strings
Get string length:
$!var.length()
Extract a substring:
$!var.substring(startIndex, endIndex)
Replace part of a string:
$!var.replace('oldValue', 'newValue')
Change case:
#set($example = 'Ukraine')
$example.toUpperCase() → UKRAINE
$example.toLowerCase() → ukraine
Accessing External Source Data
External source data can be used in Velocity when the relevant source is connected, and its values are available in the current context.
The syntax is the same Velocity syntax used for other data in Reteno.
The exact variable path depends on the structure of the returned data and the field names in the source.
Use the field names and data structure available in your source configuration or test payload.
Webhook response data
Webhook response data can be accessed with Velocity when the webhook data is available in the current workflow or message context.
Use the field names exposed by the webhook response and reference them according to the response structure.
As with other data sources, availability depends on the current context.
Updated 7 days ago
