Template Language

Template Language enables simple scripting within Templates and provides a useful method for personalisation, formatting data, iteration and placing conditional content.

Extending on what can be achieved with standard merge tags, data stored within Custom Fields can easily be manipulated to output enhanced content such as shopping basket items, booking confirmations and dynamic placement of text and images.

Merging Data

Template Language coding has full support for merge tags. To view a reference list of all available merge tags click here.

'IF' statements

An 'if' statement evaluates a condition and then provides the opportunity to place content based on the outcome:

Template Language Coding

{?if $contacts_data_1 == "sunny"?} wear shades {?/if?}

Psuedo Code

if weather is sunny then wear shades

'ELSE' Condition

'else' handles situations when the result does not match the condition:

Template Language Coding

{?if $contacts_data_1 == "sunny"?} wear shades {?else?} wear a jacket {?/if?}

Psuedo Code

if weather is sunny then wear shades, otherwise wear a jacket

'ELSEIF' and Multiple Conditions

'If' statements can be expanded to multiple levels of comparison and they can be nested to create organised structures to handle many variations.

Template Language Coding

{?if $contacts_data_1 == "sunny"?} wear shades {?elseif $contacts_data_1 == "raining"?} take an umbrella {?else?} wear a jacket {?/if?} 

Psuedo Code

if weather is sunny then wear shades, otherwise, if weather is raining take an umbrella, otherwise wear a jacket

Operators

Operators are used to define the test to be performed as part of the conditional statement.

Qualifier Syntax Example Meaning
&& $contacts_title != "" && $contacts_last_name != "" logical 'AND'
|| $contacts_first_name != "" || $contacts_last_name != "" logical 'OR'
== $contacts_data_1 == $contacts_data_2 equals
!= $contacts_data_1 != $contacts_data_2 not equals
> $contacts_data_1 > $contacts_data_2 greater than
< $contacts_data_1 < $contacts_data_2 less than
>= $contacts_data_1 >= $contacts_data_2 greater than or equal
<= $contacts_data_1 <= $contacts_data_2 less than or equal
=== $contacts_data_1 === 0 check for identity
! ! $contacts_data_1 negation (unary)
% $contacts_data_1 % $contacts_data_2 modulus
is [not] div by $contacts_data_1 is not div by 4 divisible by
is [not] even $contacts_data_1 is not even [not] an even number (unary)
is [not] even by $contacts_data_1 is not even by $contacts_data_2 grouping level [not] even
is [not] odd $contacts_data_1 is not odd [not] an odd number (unary)
is [not] odd by $contacts_data_1 is not odd by $contacts_data_2 [not] an odd grouping

Modifiers

Applying modifiers to variables enables you to format data within an Email Template.

Modifiers provide handy functions to change case, format numbers, concatenate strings and format dates.

capitalize

Capitalize the first letter of all words in a variable

Usage

{?$contacts_city?}
{?$contacts_city|capitalize?}

Output

san francisco
San Francisco

cat

Concatenate a string to the given variable.

Usage

{?$contacts_city?}
{?$contacts_city|cat:' is a great place to be'?}

Output

San Francisco
San Francisco is a great place to be

count_characters

Count the number of characters in a variable. Add :true to include whitespace.

Usage

{?$contacts_city?}
{?$contacts_city|count_characters?}
{?$contacts_city|count_characters:true?}

Output

Rio de Janeiro
12
14

count_paragraphs

Count the number of paragraphs in a variable

Usage

{?$contacts_data_1?}
{?$contacts_data_1|count_paragraphs?}

Output

Death Valley, California has the world record for hottest temperature. On 10 July 1913 a temperature of 56.7 degrees celsius was recorded
Libya is also incredibly hot, often reaching 52 degrees celsius.
2

count_sentences

Count the number of sentences in a variable

Usage

{?$contacts_data_1?}
{?$contacts_data_1|count_sentences?}

Output

Death Valley, California has the world record for hottest temperature. On 10 July 1913 a temperature of 56.7 degrees celsius was recorded.
Libya is also incredibly hot, often reaching 52 degrees celsius.
3

count_words

Count the number of words in a variable

Usage

{?$contacts_data_1?}
{?$contacts_data_1|count_words?}

Output

Death Valley, California has the world record for hottest temperature.
10

count_items

Count the number of items in an array.

Usage

{?$contacts_data_1?}
{?$json.contacts_data_1.items|@count_items?}

Output

{"items": [ { "product_code": "340440", "description": "Mens 574 Sonic Trainers", "qty": 1, "net": "75.00" }, { "product_code": "IF526", "description": "Racing Forecaster Mens Hoody Black", "qty": 1, "net": "59.99" } ]}
2

date_format

Re-formats a date and time into the given PHP strftime format.

Usage

{?$contacts_dob?}
{?$contacts_dob|date_format:"%A, %B %e, %Y"?}

Output

31/10/1970
Saturday, October 31, 1970

If the existing structure of the date being formatted cannot be automatically detected an additional parameter can be passed across to specify the format of the date being provided. This additional date mask needs to adhere to the PHP date format.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|date_format:"%A, %B %e, %Y":"d/m/Y"?}
----
{?$contacts_data_2?}
{?$contacts_data_2|date_format:"%d/%m/%y":"l, F j, Y"?}

Output

23/07/1981
Thursday, July 23, 1981
----
Saturday, October 31, 1970
31/10/70

default

Set a default (fallback) value for a variable. If the variable is unset or an empty string, the given default value is printed instead.

Usage

{?$contacts_dob|default:'Date of birth not available'?}
{?$contacts_gender|default:'Gender not available'?}

Output

31/10/1970
Gender not available

escape

Encode or escape a variable, for example html, url, single quotes, hex, hexentity, javascript and mail.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|escape:'html'?}
{?$contacts_data_1|escape:'url'?}

Output

'The Trans-Siberian Railway: the longest railway line in the world.'
'The Trans-Siberian Railway: the longest railway line in the world.'
%27The%20Trans-Siberian%20Railway%3A%20the%20longest%20railway%20line%20in%20the%20world.%27

indent

Indents a string on each line, default is 4. As an optional parameter, you can specify the number of characters to indent.

Usage

{?$contacts_data_1?}

{?$contacts_data_1|indent?}

{?$contacts_data_1|indent:10?}

Output

The Trans-Siberian Railway: the longest railway line in the world.
      The Trans-Siberian Railway: the longest railway line in the world.
           The Trans-Siberian Railway: the longest railway line in the world.

lower

Lowercase a variable.

Usage

{?$contacts_data_1?}

{?$contacts_data_1|lower?}

Output

The Trans-Siberian Railway: the longest railway line in the world.
the trans-siberian railway: the longest railway line in the world.

nl2br

All "\n" line breaks will be converted to html <br /> tags in the given variable.

Usage

{?$contacts_data_1|nl2br?}

Output

The Trans-Siberian Railway: the longest railway line in the world.
There are connecting branch lines into Mongolia, China and North Korea.

regex_replace

A regular expression search and replace on a variable.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|regex_replace:"/[t]/":"T"?}

Output

The Trans-Siberian Railway:\nthe longest railway line in the world.
The Trans-Siberian Railway: The longesT railway line in The world.

replace

A simple search and replace on a variable.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|replace:"Trans-Siberian":"Transsiberian"?}

Output

The Trans-Siberian Railway: the longest railway line in the world.
The Transsiberian Railway: the longest railway line in the world.

string_format

This is a way to format strings, such as decimal numbers and such. Use the syntax for PHP sprintf for the formatting.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|string_format:"%.2f"?}
{?$contacts_data_1|string_format:"%d"?}

Output

23.5787446
23.58
24

strip

Replaces all repeated spaces, newlines and tabs with a single space.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|strip}

Output

The Trans-Siberian Railway: the longest railway line in the world.
The Trans-Siberian Railway: the longest railway line in the world.

strip_tags

Strips out markup tags, basically anything between < and >.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|strip}

Output

The Trans-Siberian Railway: the longest railway line in the world.
The Trans-Siberian Railway: the longest railway line in the world.

sub_string

Return part of a string value using string $string|sub_string:int $start[: int $length]

Usage

{?$contacts_data_1|sub_string:0:3?}

Output

Returns the portion of string specified by the start and length parameters.

trim

Strip whitespace or other characters from the start and end of a string.

Usage

Hi {?$contacts_data_1?}
{?$contacts_data_1|trim?}
{?$contacts_data_2?}
{?$contacts_data_2|trim:"="?}

Output

Hi   Tom  
Hi Tom
====San Francisco====
San Francisco

truncate

This truncates a variable to a specific character length, the default is 80. As an optional second parameter, you can specify a string of text to display at the end if the variable was truncated. By default, truncate will attempt to cut off at a word boundary. If you want to cut off at the exact character length, pass the optional third parameter of TRUE.

Usage

{?$contacts_data_1?}
{?$contacts_data_1?}
{?$contacts_data_1|truncate?}
{?$contacts_data_1|truncate:30?}
{?$contacts_data_1|truncate:30:""?}
{?$contacts_data_1|truncate:30:"---"?}
{?$contacts_data_1|truncate:30:"":true?}
{?$contacts_data_1|truncate:30:"...":true?}
{?$contacts_data_1|truncate:30:'..':true:true?}

Output

The Trans-Siberian Railway: the longest railway line in the world. There are connecting branch lines into Mongolia, China and North Korea.
The Trans-Siberian Railway: the longest railway line in the world. There are connecting branch lines into Mongolia, China and North Korea.
The Trans-Siberian Railway: the longest railway line in the world. There are...
The Trans-Siberian Railway:...
The Trans-Siberian Railway:
The Trans-Siberian Railway:---
The Trans-Siberian Railway: th
The Trans-Siberian Railway:...
The Trans-Sibe..d North Korea.

upper

Uppercase a variable

Usage

{?$contacts_data_1?}
{?$contacts_data_1|upper?}

Output

The Trans-Siberian Railway: the longest railway line in the world.
THE TRANS-SIBERIAN RAILWAY: THE LONGEST RAILWAY LINE IN THE WORLD.

wordwrap

Wraps a string to a column width, the default is 80.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|wordwrap:30?}

Output

The Trans-Siberian Railway:
the longest railway line in
the world.

json_encode

Display the contents of an Array of data, primarily used to debug the contents of an array when resolving display issues.

Usage

{?$json.contacts_data_1|@json_encode?}

Output

{"customer":{"first_name":"Joe","last_name":"Bloggs","account":"CR024676"},"order":{"invoice":"AYD24367","order_total":"134.99","currency_symbol":"\u00a3","delivery_date":"","address":{"line_1":"10 Station Road","line_2":"","city":"Birmingham","county":"West Midlands","country":"UK","postcode":"B1 2CD"},"items":[{"product_code":"340440","description":"Mens 574 Sonic Trainers","qty":1,"net":"75.00"},{"product_code":"IF526","description":"Racing Forecaster Mens Hoody Black","qty":1,"net":"59.99"}]}}

date_compare

This modifier will perform a comparison on the specified date, checking whether it occurs before or after a target date or in between a set of two dates. This modifier returns either true or false depending on whether the conditions are met.

For date comparisons the first parameter determines the type of comparison, this is either 'before', 'after' or 'between'. When checking if a date occurs before or after a specified date, the second parameter defines the date being compared against:

Usage

{?$contacts_data_1?}
{?if $contacts_data_1|date_compare:'after':'2021-10-31'?}
    This date occurs after 2021-10-31
{?/if?}

Output

2021-11-01
This date occurs after 2021-10-31

Merge data can also be used in place of target dates:

Usage

{?$contacts_data_1?}
{?$contacts_data_2?}
{?if $contacts_data_1|date_compare:'after':$contacts_data_2?}
    This date occurs after {?$contacts_data_2?}
{?/if?}

Output

2021-11-01
2021-10-31
This date occurs after 2021-10-31

When checking if the date occurs between two dates, the second and third parameters define the date span for the comparison:

Usage

{?$contacts_data_1?}
{?if $contacts_data_1|date_compare:'between':'2021-10-31':'2021-11-30'?}
    This date occurs between 2021-10-31 and 2021-11-30
{?/if?}

Output

2021-11-01
This date occurs between 2021-10-31 and 2021-11-30

Date modifiers work reliably when an unambiguous format, such as YYYY-MM-DD, is used. For dates outside of this format a parameter can be added to define the format of the dates being processed. All dates must be in the same date format when being compared. Date format strings use the PHP date format.

Usage

{?$contacts_data_1?}
{?if $contacts_data_1|date_compare:'after':'31/10/2021':'d/m/Y'?}
    This date occurs after 31/10/2021
{?/if?}

Output

01/11/2021
This date occurs after 31/10/2021

days_until

This modifier returns the number of days until the specified date. Note that this modifier can generate negative numbers if the date has already passed.

Date modifiers work reliably when an unambiguous format, such as YYYY-MM-DD, is used. For dates outside of this format a parameter can be added to define the format of the dates being processed. Date format strings use the PHP date format.

Usage

{?$contacts_data_1?}
{?if $contacts_data_1|days_until:'d/m/Y' > 7?}
    This date is more than 7 days away
{?/if?}

Output

31/10/2021
This date is more than 7 days away

days_after

This modifier returns the number of days after the specified date. Note that this modifier can generate negative numbers if the date hasn't passed yet.

Date modifiers work reliably when an unambiguous format, such as YYYY-MM-DD, is used. For dates outside of this format a parameter can be added to define the format of the dates being processed. Date format strings use the PHP date format.

Usage

{?$contacts_data_1?}
{?if $contacts_data_1|days_after > 7?}
    This date was more than 7 days ago
{?/if?}

Output

2021-06-01
This date was more than 7 days ago

modify_date

This modifier is used to add or subtract units of time (minutes, days, months, etc) from the specified date.

The first parameter determines the amount to add or remove from the specified date. This number should always be prefixed with a + or - symbol; when adding a unit of time the number should be prefixed with a + symbol and when subtracting a unit of time the number should be prefixed with a - symbol.

The second parameter determines the unit of time to be adjusted on the specified date and should be one of the following: 'seconds', 'minutes', 'hours', 'days', 'weeks', 'months' or 'years'.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|modify_date:"+1":"years"?}
{?$contacts_data_1|modify_date:"+1":"months"?}
{?$contacts_data_1|modify_date:"-2":"weeks"?}
{?$contacts_data_1|modify_date:"+3":"days"?}

Output

2023-01-31
2024-01-31
2023-02-28
2023-01-17
2023-02-03

The date returned by this modifier is always in the standard 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' formats, the latter is used if a time component other than 00:00:00 is present.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|modify_date:"+30":"seconds"?}
{?$contacts_data_1|modify_date:"+90":"minutes"?}
{?$contacts_data_1|modify_date:"-90":"minutes"?}
{?$contacts_data_1|modify_date:"+10":"hours"?}

Output

2023-01-31 15:00:00
2023-01-31 15:00:30
2023-01-31 16:30:00
2023-01-31 13:30:00
2023-02-01 01:00:00

If specific formatting of the returned date is required, the date_format modifier can be added to change the output format.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|modify_date:"+1":"months"|date_format:"%d/%m/%y"?}
{?$contacts_data_1|modify_date:"+1":"months"|date_format:"%m/%d/%y %H:%M:%S"?}
{?$contacts_data_1|modify_date:"+1":"months"|date_format:"%A, %B %e, %Y"?}
{?$contacts_data_1|modify_date:"+1":"months"|date_format:"%s"?}

Output

2023-01-31 15:00:00
28/02/23
02/28/23 15:00:00
Tuesday, February 28, 2023
1677596400

Date modifiers work reliably when an unambiguous format, such as YYYY-MM-DD, is used. For dates outside of this format a third parameter can be added to define the format of the dates being processed. Date format strings use the PHP date format.

Usage

{?$contacts_data_1?}
{?$contacts_data_1|modify_date:"+1":"weeks":"d/m/y"?}
{?$contacts_data_1|modify_date:"+1":"weeks":"d/m/y"|date_format:"%d/%m/%y"?}

{?$contacts_data_2?}
{?$contacts_data_2|modify_date:"+1":"weeks":"m/d/y"?}
{?$contacts_data_2|modify_date:"+1":"weeks":"d/m/y"|date_format:"%m/%d/%y"?}

Output

31/01/23
2023-02-07
07/02/23

07/31/23
2023-02-07
02/07/23

Arrays & Iteration

Custom Field Array Data presents information to the Template Language as array objects, which can be manipulated in a variety of ways.

The example usages below assume JSON encoded sample data is stored within the contacts_data_1 Custom Field:

{
    "customer": {
        "first_name": "Joe",
        "last_name": "Bloggs",
        "account": "CR024676"
    },
    "order": {
        "invoice": "AYD24367",
        "order_total": "134.99",
        "currency_symbol": "\u00a3",
        "delivery_date": "",
        "address": {
            "line_1": "10 Station Road",
            "line_2": "",
            "city": "Birmingham",
            "county": "West Midlands",
            "country": "UK",
            "postcode": "B1 2CD"
        },
        "items": [
            {
                "product_code": "340440",
                "description": "Mens 574 Sonic Trainers",
                "qty": 1,
                "net": "75.00"
            },
            {
                "product_code": "IF526",
                "description": "Racing Forecaster Mens Hoody Black",
                "qty": 1,
                "net": "59.99"
            }
        ]
    }
}

Accessing Specific Elements

Specific elements of an array can be accessed using dot notation.

Usage

{?$json.contacts_data_1.customer.first_name?}
{?$json.contacts_data_1.customer.last_name?}
{?$json.contacts_data_1.order.invoice?}
{?$json.contacts_data_1.order.address.line_1?}
{?$json.contacts_data_1.order.items.0.product_code?}
{?$json.contacts_data_1.order.items.1.product_code?}

Output

Joe
Bloggs
AYD24367
10 Station Road
340440
IF526

Foreach

Loop through either associative or sequential repeating array items using {?foreach?}.

The {?foreach?} tag has two required parameters - 'from' specifies the array item being looped over, and 'item' is the name used to reference the current array item within the loop construct.

{?foreachelse?} can be used to specify content for when there are no values present within the 'from' parameter.

An optional 'key' parameter can be provided to access the key of the current array item, this can be used for both numerically indexed and associative arrays.

Usage

----------------
{?foreach from=$json.contacts_data_1.order.items key='key' item='product'?}
    {?$key?}
    {?$product.product_code?}
    {?$product.description?}
    {?$product.qty?}
    {?$product.net?}
    ----------------
{?foreachelse?}
Please contact us for your product details.
----------------
{?/foreach?}

Output


0
340440
Mens 574 Sonic Trainers
1
75.00


1
IF526
Racing Forecaster Mens Hoody Black
1
59.99


Section

Loop through sequentially indexed arrays of data, or create simple loops using {?section?}.

The {?section?} tag has two required parameters - 'name' and 'loop'. The 'name' parameter specifies the label for the section, and is used to print the contents of variables. The 'loop' parameter can either be an array of values or a single integer value and specifies the number of times the {?section?} will loop.

{?sectionelse?} can be used to specify content for when there are no values in the loop parameter.

When 'loop' is specified as an integer, optional 'start' and 'step' parameters can be used to specify the starting position of the loop index and the number of indexes stepped through on each iteration.

Usage

{?section name=products loop=$json.contacts_data_1.order.items?}
    {?$json.contacts_data_1.order.items[products].product_code?}
{?/section?}

{?section name=products loop=2?}
    {?$json.contacts_data_1.order.items[products].product_code?}
{?/section?}

{?section name=counting_loop loop=10 start=1 step=2?}
    {?$smarty.section.counting_loop.index?}
{?/section?}

Output

340440
IF526

340440
IF526

1
3
5
7
9

Debugging

If email tests aren't rendering as expected it is possible to write out the contents of arrays into the template itself to see the exact format the data has been stored in. This can be done using the |@json_encode modifier.

Using the example array above, if the data was stored in contacts_data_1, the contents can be output as below:

Usage

{?$json.contacts_data_1|@json_encode?}

Output

{"customer":{"first_name":"Joe","last_name":"Bloggs","account":"CR024676"},"order":{"invoice":"AYD24367","order_total":"134.99","currency_symbol":"\u00a3","delivery_date":"","address":{"line_1":"10 Station Road","line_2":"","city":"Birmingham","county":"West Midlands","country":"UK","postcode":"B1 2CD"},"items":[{"product_code":"340440","description":"Mens 574 Sonic Trainers","qty":1,"net":"75.00"},{"product_code":"IF526","description":"Racing Forecaster Mens Hoody Black","qty":1,"net":"59.99"}]}}

Related Pages