Documentation

1Introduction

This document describes the syntax and semantics of the twig templates and it should serve as a reference for creating or customizing one. Please bare in mind, that we use a customized Twig template engine which contains only a subset of Twig’s features. All the features which are applicable are described in the sections below.

1.1Synopsis

A template is simply a text file which can be used to generate any text-based format (HTML, PDF, etc.). As a convention all our template files have a .twig extension.

A template contains variables or expressions, which get replaced with values when the template is evaluated, and tags, which control the logic of the template. Below is a minimal template that illustrates a few basics. We will cover further details later on:

<!DOCTYPE html>
<html>
	<head>
		<title>My Title</title>
	</head>
	<body>
		<h1>Welcome to {{ shopName }}</h1>
		<ul>
		{% for product in products %}
		    <li><a href="{{ product.href }}">{{ product.name }}</a></li>
		{% endfor %}
		</ul>
	</body>
</html>

1.2Syntax

There are two primary delimiters used within a twig template: {% …​ %} and {{ …​ }}. The first one is used to execute statements which can change the control flow of the template (if-statement), include a template, define a new block, etc. The second one will print the result of an expression to the template. Expressions can be very simple (e.g. a variable name) or much more complex (e.g. a mathematical expression).

1.3Variables

The application passes variables to the templates for manipulation in the template. Variables may have attributes or elements you can access, too. The visual representation of a variable depends heavily on the application providing it.

You can use a dot . to access attributes of a variable.

{{ user.firstName }}
Note

It is important to know that the curly braces are not part of the variable but the print statement. When accessing variables inside tags, don’t put the braces around them.

You can assign values to variables inside code blocks using the set tag:

{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}

1.4Comments

To comment-out part of a line in a template, use the comment syntax {# …​ #}. This is useful for debugging or to add information for other template designers or yourself:

{# Note: disabled template because we no longer use this.
    {% for item in items %}
        ...
    {% endfor %}
#}

1.5Control Structure

A control structure refers to all those things that control the flow of a program - conditionals (i.e. if/elseif/else), for-loops, as well as things like blocks. Control structures appear inside {% …​ %} blocks. For example, to display a list of users provided in a variable called users, use the for tag:

<h1>Members</h1>
<ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
</ul>

The if tag can be used to test an expression:

{% if users | length > 0 %}
    <ul>
        {% for user in users %}
            <li>{{ user.username }}</li>
        {% endfor %}
    </ul>
{% endif %}

1.6Template Inheritance

The most powerful feature is template inheritance. Template inheritance allows you to build a base "skeleton" template that contains all the common elements of your site and defines blocks that child templates can override. For brief explanations how you can inherit a template and customize only part of it, refer to extends and block tags.

1.7Escaping

XSS vulnerabilites are the most common types of security vulnerabilities in web applications and in order to avoid them you must escape potentially unsafe data before presenting it to the end user. Within all twig templates the autoescaping is enabled by default. Autoescaping can be turned off, in which case autoescape tag and escape filter can be used for more fine-grained manual escaping.

1.7.1Autoescaping

Autoescaping, which is enabled by default, will automatically escape the outcome of expressions contained within print delimiters ({{ and }}):

{% set danger = "<br>" %}
{{ danger }}

{# output: &lt;br&gt; #}

The raw filter can be used to prevent the autoescaper from escaping a particular expression. It is important that the raw filter is the last operation performed in the expression.

{% set danger = "<br>" %}
{{ danger | raw }}

{# output: <br> #}

If the raw filter is not the last operation performed within the expression, the expression will be deemed as possibly unsafe by the autoescaper and will be escaped:

{% set danger = "<br>" %}
{{ danger | raw | uppercase }}

{# will output: &lt;BR&gt; #}
Note

If the expression only contains a string literal, it is assumed to be safe and will not be escaped.

{% set hello = "<strong>Hello</strong>" %}
{{ hello }}
{{ "<strong>world</strong>" }} {# static expression #}

The above example will be rendered as "<strong>Hello</strong> world".

1.7.2Manual Escaping

If autoescaping is disabled you can still use the escape filter to aid with manual escaping:

{% set danger = "<br>" %}
{{ danger | escape }}

{# output: &lt;br&gt; #}

1.7.3Strategies

When escaping data it is crucial that you utilize the correct escaping strategy depending on the context of the data. By default, the autoescape tag and the escape filter assume that you are escaping HTML data.

The following escaping strategies are supported:

css

The css strategy escapes a string for the CSS context. CSS escaping can be applied to any string being inserted into CSS and escapes everything except alphanumerics.

html

The html strategy escapes a string for the HTML body context.

html_attr

The html_attr strategy escapes a string for the HTML attribute context.

js

The js strategy escapes a string for the JavaScript context.

url_param

The url_param strategy escapes a string for the URL parameter contexts. This should not be used to escape an entire URL.

2Functions

Functions can be called to generate content. Functions are called by their name followed by parentheses (()) and may have arguments.

2.1Arguments

Dates to return range for.

2.2Return Value

String representation of date range.

2.3datetimeRange

The datetimeRange function is used to format date ranges with date and time information. The formatting takes current user’s locale into consideration while formatting.

{# lowerDate = 2018-01-01 00:00:00 #}
{# lowerDate = 2018-02-01 23:59:59 #}
{{ datetimeRange(lowerDate, upperDate) }}

If user’s locale is English USA (en_US), the output would be:

Jan 01, 2018 - Feb 01, 2018

If user’s locale is German (de_DE), the output would be:

01.01.2018 - 01.02.2018

2.3.1Arguments

lower

The range’s lower limit.

upper

The range’s upper limit.

2.3.2Return Value

The datetimeRange filter returns a string.

2.4json

The json function returns the JSON representation of a value:

<select id="state-selection" data-options="{{ json(states) | escape('html_attr') }}">
	<option value=""></option>
	{% for state in country.states %}
		<option value="{{ state.id }}"
			{{ state.name }}
		</option>
	{% endfor %}
</select>

2.4.1Arguments

variable

The variable which should be represented as a JSON string.

2.4.2Return Value

The json function returns a string.

2.5max

The max function will return the largest of its numerical arguments.

{{ max(4, 8, 15, 16, 23, 42) }}
{# output: 42 #}

2.5.1Arguments

The max function accepts variable number of numerical arguments.

2.5.2Return Value

The max function returns a number.

2.6min

The min function will return the smallest of its numerical arguments.

{{ min(4, 8, 15, 16, 23, 42) }}
{# output: 4 #}

2.6.1Arguments

The min function accepts variable number of numerical arguments.

2.6.2Return Value

The min function returns a number.

2.7range

The range function returns a list containing an arithmetic progression of numbers:

{% for i in range(0, 3) %}
    {{ i }},
{% endfor %}

{# output: 0, 1, 2, 3, #}

2.7.1Arguments

start

The start is the frist argument of range function and represents starting number.

end

The end is the second argument of range function and represents last number.

increment

The increment is the third argument of range function and represents the step. The increment is optional. If not provided the default increment step is 1.

2.7.2Return Value

The range function returns a collection of numbers.

3Filters

Variables can be modified by filters. Filters are separated from the variable by a pipe symbol (|) and may have optional arguments in parentheses.

{{ variable | filter }}

The following code is example of join filter which takes delimiter as an argument:

{{ list | join(', ') }}

Multiple filters can be chained together. The output of one filter is applied to the next.

{{ variable | escape | title }}

3.1abbreviate

The abbreviate filter will abbreviate a string using an ellipsis (…​). It takes one argument which is the maximal length of the desired output including the length of the ellipsis.

{{ "this is a long sentence." | abbreviate(7) }}

The above example will output the following:

this...

3.1.1Arguments

length

The length to which input string should be abbreviated. The length argument must not be less than zero.

3.1.2Return Value

The abbreviate filter returns a string.

3.2abs

The abs filter takes a number as the input and returns its absolute value.

{% set number = -9 %}

{{ number | abs }}

{# output: 9 #}

3.2.1Arguments

The abs filter has no arguments.

3.2.2Return Value

The abs filter retuns a number.

3.3barCode

The barCode filter generates a bar code image link with specified parameters.

{{ 'sometext' | barCode }}

This will generate an image tag. The image will point to an URL which renders sometext as a bar code or QR code.

<img src="https://some-url">

Different types of bar codes have different restrictions on length or what characters can be a part of the string:

  • QR_CODE: Maximum length 300 characters.

  • CODE_128: Maximum length 80 characters, ASCII characters only.

  • EAN_8: Maximum length 7 or 8 characters, digits only. When the code is 7 digits long, the check digit will be automatically calculated and added to the code. When the code is 8 digits long, the check digit must be correct.

  • EAN_13: Maximum length 12 or 13 characters, digits only. When the code is 12 digits long, the check digit will be automatically calculated and added to the code. When the code is 13 digits long, the check digit must be correct.

3.3.1Arguments

type

The type argument indicates the type of the bar code. If not specified, it defaults to CODE_128. Possible values: QR_CODE, EAN_8, EAN_13 and CODE_128 (default).

maxWidth

This argument indicates the maximum width of the bar code image. When not specified, it defaults to 200 pixels. The maximum value is 500 pixels. Other units will be converted with 72 DPI. Depending on the code and the available space, the resulting rendered code width may be smaller, but it will never be bigger.

maxHeight

This argument indicates the maximum height of the bar code image. When not specified, it defaults to the same value as the width for QR-code or to 1/3 of the width for linear codes. The maximum value is 500 pixels. Other units will be converted with 72 DPI. Depending on the code and the available space, the resulting rendered code height may be smaller, but it will never be bigger.

unit

The unit of measurement for width and height. When not specified, the default value is PIXELS (screen or print pixels). Possible values are: MM (millimetres), IN (inches) and PIXELS (screen or print pixels). When specifying units other than PIXELS the calculation is done based on the 72 pixels per inch value.

3.3.2Return Value

The barCode filter returns a string with the corresponding HTML code, as shown in the example.

3.4capitalize

The capitalize filter capitalizes the first letter of the input string. See also title filter.

{{ "article title" | capitalize }}

The above example will output the following:

Article title

3.4.1Arguments

The capitalize filter has no arguments.

3.4.2Return Value

The capitalize filter retuns a string.

3.5darken

The darken filter decreased the lightness of a color in the HSL color space by an absolute amount.

{{ '#ffffff' | darken(10) }}

{# output: rgba(230, 230, 230, 1) #}

3.5.1Arguments

amount

The amount argument represents the percent amount that the color’s lightness should be decreased by. If the amount is not provided, 1 is used instead.

3.5.2Return Value

The darken filter returns the new color.

3.6date

The date filter is used to format date. The formatting takes current user’s locale into consideration while formatting.

{# user.dateOfBirth = 'October 21, 2015' #}

{{ user.dateOfBirth | date }}

If user’s locale is English USA (en_US), the output would be:

21-Oct-2015

If user’s locale is German (de_DE), the output would be:

21.10.2015

3.6.1Arguments

defaultValue

The date filter can accept a defaultValue argument which is returned if input date is null.

3.6.2Return Value

The date filter retuns a string.

3.7datetime

The datetime filter is used to format date with date and time information. The formatting takes current user’s locale into consideration while formatting.

{{ transaction.createdOn | datetime }}

If user’s locale is English USA (en_US), the output would be:

Oct 20, 2015 11:00:00 PM

If user’s locale is German (de_DE), the output would be:

20.10.2015 23:00:00

3.7.1Arguments

defaultValue

The datetime filter can accept a defaultValue argument which is returned if input date is null.

3.7.2Return Value

The datetime filter retuns a string.

3.8default

The default filter will render a default value if and only if the value being filtered is empty. A variable is empty if it is null, an empty string, an empty collection, or an empty map.

{{ billingAddress.phoneNumber | default("No phone number") }}

{{ '' | default('passed variable is empty')  }}

In the following example, if foo, bar, or baz are null the output will become an empty string which is a perfect use case for the default filter:

{{ foo.bar.baz | default("No baz") }}

3.8.1Arguments

default

The default filter has argument called default which is returned in case when input value is empty.

3.8.2Return Value

The default filter returns input value if it is not empty, otherwise returns the value passed as the argument.

3.9escape

The escape filter escapes a string, to avoid XSS vulnerability, for safe insertion into the final output. It supports different escaping strategies depending on the template context.

Note

By default, the escape filter uses the HTML escaping strategy:

{% autoescape false %}

	{{ "<div>" | escape }}

{% endautoescape %}

{# output: &lt;div&gt; #}

The above example is equivalent to:

{% autoescape false %}

	{{ "<div>" | escape('html') }}

{% endautoescape %}

{# output: &lt;div&gt; #}

Please read the escaping section for more information about escaping.

3.9.1Arguments

strategy

For the full list of escaping strategies refer to strategies section.

3.9.2Return Value

The escape filter returns a string value.

3.10first

The first filter will return the first item of a collection, or the first letter of a string.

{{ ["Alex", "Joe", "Bob"] | first }}
{# will output: 'Alex' #}

{{ 'John' | first }}
{# will output: 'J' #}

3.10.1Arguments

The first filter has no arguments.

3.10.2Return Value

The return value of first filter depends on the input. If the input is collection then the return value is first element of the collection. If the input is string the output is also a string.

3.11formatAddress

The formatAddress filter is used to format a modular address.

<div class="customerAddress">
	{% for line in transaction.billingAddress | formatAddress(false) %}
		{{ line }}<br />
	{% endfor %}
</div>

3.11.1Arguments

The formatAddress filter has one optional argument excludeCountryLine which allows to skip the country line of the address. The argument excludeCountryLine must be a boolean. The default behavior is to include the country line.

3.11.2Return Value

The formatAddress filter returns a list of strings, each representing a line of address.

3.12formatAmount

The formatAmount filter formats a given number based on the passed currency and current user locale. The arguments described below can be used to override the locale settings.

{{ transaction.authorizationAmount | formatAmount(transaction.currency) }}

3.12.1Arguments

currency

The currency is used to format the given amount.

allowedDigits

The maximum allowed number of decimal digits. When not specified, the value will be taken from the number of decimal digits that exist in the specified currency. E.g., for the currency CHF this value would be 2, and for JPY it would be 0.

symbolPosition

Determines where the currency symbol should be placed. The possible values are:

  • BEFORE The currency symbol should be placed before the amount: CHF 100.

  • AFTER The currency symbol should be placed after the amount: 100 CHF.

  • FROM_LOCALE The default value, it indicates that the applied style will be determined from the current user’s locale / language.

negativeStyle

Determines the style of how the negative numbers are displayed. The possible values are:

  • MINUS Use the minus sign to show negative numbers such as -100 CHF.

  • BRACKETS Use brackets to display negative values such as (100 CHF).

  • FROM_LOCALE The default value, it indicates that the applied style will be determined from the current user’s locale / language.

spacing

Determines whether there should be a space between the currency symbol or amount. The possible values are:

  • ALWAYS There should be always a space between the currency and the amount: CHF 100 or 100 CHF.

  • NEVER There should not be a space between the currency and the amount: CHF100 or 100CHF.

  • FROM_LOCALE The default value, it indicates that the applied style will be determined from the current user’s locale / language.

symbol

Determines whether the currency should be displayed with its 3-letter ISO code or with a localized symbol. The possible values are:

  • ISO_CODE Display the currency with the 3-letter ISO code: 100 CHF. This is the default value.

  • SYMBOL Display the currency with a localized symbol, e.g. in German locale: 100 SFr..

3.12.2Return Value

The formatAmount filter returns a string which contains the formated amount.

3.13join

The join filter will concatenate all items of a collection or array into a string. An optional argument can be given to be used as the separator between items.

{{ ["Alex", "Joe", "Bob"] | join(', ') }}
{# will output: Alex, Joe, Bob #}

{{ ["Alex", "Joe", "Bob"] | join }}
{# will output: AlexJoeBob #}

3.13.1Arguments

separator

The separator is string used to separate the collection elements. The separator is optional.

3.13.2Return Value

A String, representing the collection elements, separated by the specified separator.

3.14last

The last filter will return the last item of a collection, or the last letter of a string.

{{ [1, 2, 3, 4, 5] | last }}
{# will output: 5 #}

{{ 'Apple' | last }}
{# will output: 'e' #}

3.14.1Arguments

The last filter has no arguments.

3.14.2Return Value

The return value of last filter depends on the input. If the input is collection then the return value is last element of the collection. If the input is string the output is also a string.

3.15length

The length filter returns the number of items of collection, map or the length of a string:

{{ ["Apple", "Orange", "Mango"] | length }}

{# will output: 3 #}

The length filter can be used inside if tag to make as a conditional

{% if users|length > 10 %}
    ...
{% endif %}

3.15.1Arguments

The length filter has no arguments.

3.15.2Return Value

The length filter returns a number.

3.16lighten

The lighten filter increased the lightness of a color in the HSL color space by an absolute amount.

{{ '#000000' | lighten(10) }}

{# output: rgba(26, 26, 26, 1) #}

3.16.1Arguments

amount

The amount argument represents the percent amount that the color’s lightness should be increased by. If the amount is not provided, 1 is used instead.

3.16.2Return Value

The lighten filter returns the new color.

3.17lineItemTotalAmountExcludingTax

The lineItemTotalAmountExcludingTax filter calculates the total amount without taxes from a list of line items.

{{ lineItems | lineItemTotalAmountExcludingTax }}

The above example will output the following:

101.12

3.17.1Return Value

The lineItemTotalAmountExcludingTax filter returns the total amount without any tax.

3.18lineItemTotalAmountIncludingTax

The lineItemTotalAmountIncludingTax filter calculates the total amount with taxes from a list of line items.

{{ lineItems | lineItemTotalAmountIncludingTax }}

The above example will output the following:

101.12

3.18.1Return Value

The lineItemTotalAmountIncludingTax filter returns the total amount with taxes applied.

3.19lineItemTotalDiscountExcludingTax

The lineItemTotalDiscountExcludingTax filter calculates the total discount excluding taxes from a list of line items.

{{ lineItems | lineItemTotalDiscountExcludingTax }}

The above example will output the following:

10.12

3.19.1Return Value

The lineItemTotalDiscountIncludingTax filter returns the total discount without any tax applied.

3.20lineItemTotalDiscountIncludingTax

The lineItemTotalDiscountIncludingTax filter calculates the total discount including taxes from a list of line items.

{{ lineItems | lineItemTotalDiscountIncludingTax }}

The above example will output the following:

10.12

3.20.1Return Value

The lineItemTotalDiscountIncludingTax filter returns the total discount with tax.

3.21lineItemTotalTaxAmount

The lineItemTotalTaxAmount filter calculates the total tax amount from a list of line items.

{{ lineItems | lineItemTotalTaxAmount }}

The above example will output the following:

101.12

3.21.1Return Value

The lineItemTotalTaxAmount filter returns the total tax amount from a list of line items.

3.22lineItemTotalTaxAmountsByRate

The lineItemTotalTaxAmountsByRate filter calculates the total tax amounts per tax rate from a list of line items.

{{ lineItems | lineItemTotalTaxAmountsByRate(currency) }}

The above example will output the following:

[Tax [title=Rate 1, rate=10, amount=55.76], Tax [title=Rate 2, rate=3.5, amount=0.55]]

3.22.1Return Value

The lineItemTotalTaxAmountsByRate filter returns the total tax amounts per tax rate from a list of line items.

3.23lineItemTotalUndiscountedAmountExcludingTax

The lineItemTotalUndiscountedAmountExcludingTax filter calculates the total undiscounted amount without taxes from a list of line items.

{{ lineItems | lineItemTotalUndiscountedAmountExcludingTax }}

The above example will output the following:

101.12

3.23.1Return Value

The lineItemTotalUndiscountedAmountExcludingTax filter returns the total undiscounted amount without any tax.

3.24lineItemTotalUndiscountedAmountIncludingTax

The lineItemTotalUndiscountedAmountIncludingTax filter calculates the total undiscounted amount including taxes from a list of line items.

{{ lineItems | lineItemTotalUndiscountedAmountIncludingTax }}

The above example will output the following:

101.12

3.24.1Return Value

The lineItemTotalUndiscountedAmountIncludingTax filter returns the total undiscounted amount with applied taxes.

3.25lower

The lower filter converts all letters of an input string into lower case.

{{ "THIS IS A LOUD SENTENCE" | lower }}

The above example will output the following:

this is a loud sentence

3.25.1Arguments

The lower filter has no arguments.

3.25.2Return Value

The return value of the lower filter is string.

3.26negate

The negate filter takes a number as the input and returns its negative value.

{% set number = 9 %}

{{ number | negate }}

{# output: -9 #}

3.26.1Arguments

The negate filter has no arguments.

3.26.2Return Value

The negate filter retuns a number.

3.27numberformat

The numberformat filter is used to format a decimal number.

{{ 3.141592653 | numberformat("#.##") }}

{# output: 3.14 #}

You can round the decimal number to whole number by not defining fractional numbers:

Note

The rounding of decimal number is applied by default, if number of fractional digits of the input number is bigger than number of fractional digits allowed by format pattern.

{{ 3.5 | numberformat("#") }}
{# output: 4 #}

{{ 3.3 | numberformat("#") }}
{# output: 3 #}

To define different formats for positive and negative numbers use ; to separate positive and negative sub-patterns.

{% set format = '###,###.##;-###,###.##' %}

{% set number = 1234 %}
{{ number | numberformat(format) }}
{# output: 1,234 #}

{% set number = -1234 %}
{{ number | numberformat(format) }}
{# output: -1,234 #}

You can use any digit from 0 to 9 in format pattern which will be output literally if the number is .

To format number always with two fractional digits even if the number is not decimal, you can define following format:

{{ 7 | numberformat("#.00") }}
{# output: 7.00 #}

{{ 7 | numberformat("#.99") }}
{# output: 7.99 #}

{{ 123.4 | numberformat("#.00") }}
{# output: 123.40 #}

{{ 123.45 | numberformat("#.00") }}
{# output: 123.45 #}

Another use of digits can be if you want to prefix number smaller than format:

{{ 7 | numberformat('000.##') }}
{# output: 007 #}

3.27.1Arguments

format

The format argument represents a pattern, used to format input number. Many characters in a pattern are taken literally, they are output unchanged during formatting. Special characters, on the other hand, stand for other characters, strings, or classes of characters. They must be quoted if they are to appear in the prefix or suffix as literals. The characters listed here are used in formating

Character Location Meaning

0-9

Number

Digit

#

Number

Digit, zero shows as absent

.

Number

Decimal separator or monetary decimal separator

-

Number

Minus sign

,

Number

Minus sign

E

Number

Separates mantissa and exponent in scientific notation. Need not be quoted in prefix or suffix.

;

Subpattern boundary

Separates positive and negative sub-patterns. It is important to note that the first pattern (before ; character) is used for formatting positive number and second, for negative.

%

Prefix or suffix

Multiply number by 100 and show as percentage

Prefix or suffix

Multiply number by 1000 and show as per mille value

'

Prefix or suffix

Used to quote special characters in a prefix or suffix, for example, '#'# formats 123 to #123. To create a single quote itself, use two in a row: # o''clock.

3.27.2Return Value

The numberformat returns a string.

3.28qrCode

The qrCode filter generates a bar code image link with specified parameters.

{{ 'sometext' | qrCode }}

This will generate an image tag. The image will point to an URL which renders sometext as a QR code.

<img src="https://some-url">

3.28.1Return Value

The qrCode filter returns a string with the corresponding HTML code, as shown in the example.

3.29raw

The raw filter prevents the output of an expression from being escaped by the autoescaper. The raw filter must be the very last operation performed within the expression otherwise the autoescaper will deem the expression as potentially unsafe and escape it regardless.

{% set danger = "<div>" %}

{{ danger | upper | raw }}

{# output: <DIV> #}

If the raw filter is not the last operation performed then the expression will be escaped:

{% set danger = "<div>" %}

{{ danger | raw | upper }}

{# output: &lt;DIV&gt; #}

3.29.1Arguments

The raw filter has no arguments.

3.29.2Return Value

The raw filter returns a string if an input value is string, or the passed object unchanged.

3.30regexp

The regexp filter formats a regular expression so it can be used in JavaScript.

3.30.1Arguments

The regexp filter has no arguments.

3.30.2Return Value

The regexp filter retuns a string.

3.31replace

The replace filter formats a given string by replacing the placeholders (placeholders are free-form):

{% set this = 'trains' %}

{{ "I like %this% and %that%." | replace({'%this%': this, '%that%': "planes"}) }}

{# output: I like trains and planes. #}

3.31.1Arguments

replace_pairs

The replace_pairs argument accept pairs of placeholder and replacement delimited by colon (:). Pairs are separated by comma (,).

3.31.2Return Value

The replace filter retuns a string.

3.32resourcepath

The resourcepath filter takes a relative resource path and returns a fully qualified URL (Uniform Resource Locator) to a resource.

<img src="{{ brand.imagePath | resourcepath }}" />

3.32.1Arguments

The resourcepath filter has no arguments.

3.32.2Return Value

The resourcepath filter retuns a string.

3.33round

The round filter takes a number as the input and returns the rounded value.

{% set number = 9.81 %}

{{ number | round }}

{# output: 10 #}

3.33.1Arguments

The round filter has no arguments.

3.33.2Return Value

The round filter retuns a number.

3.34rsort

The rsort filter will sort an input list in reversed order.

{% set fruits = [ "Orange", "Avocado", "Kiwi", "Banana"] %}

{{ fruits | rsort }}

{# output: [Orange, Kiwi, Banana, Avocado] #}

3.34.1Arguments

The rsort filter has no arguments.

3.34.2Return Value

The rsort filter returns an original input list sorted in reverse order.

3.35slice

The slice filter returns a portion of a list, array or string.

{{ ['Apple', 'Peach', 'Pear', 'Banana'] | slice(1,3) }}
{# output: [Peach, Pear] #}

{{ 'Apple' | slice(1,3) }}
{# output: pp #}

3.35.1Arguments

fromIndex

The fromIndex argument is zero-based and inclusive.

toIndex

The toIndex argument is zero-based and exclusive.

Note

Zero-based means that numbering of elements in a list starts at 0. The initial element of the list is assigned the index 0, rather than the index 1.

3.35.2Return Value

The slice filter returns a portion of a list or array elements if input value is list or array. When input value is string, the output of slice filter is string.

3.36sort

The sort filter will sort an input list in reversed order.

{% set fruits = [ "Orange", "Avocado", "Kiwi", "Banana"] %}

{{ fruits | sort }}

{# output: [Avocado, Banana, Kiwi, Orange] #}

3.36.1Arguments

The sort filter has no arguments.

3.36.2Return Value

The sort filter returns an original input list which is sorted.

3.37split

The split filter splits an input string by the given separator and returns a list of strings:

{% set input = "one,two,three" %}

{% set output = input | split(',')  %}

{# output contains ['one', 'two', 'three'] #}

If a separator is an empty string, then the input value will be split into a list of characters.

{% set input = "Lemonade" %}

{% set output = input | split('')  %}

{# output contains ['L', 'e', 'm', 'o', 'n', 'a', 'd', 'e'] #}

3.37.1Arguments

separator

The separator argument represents the delimiting regular expression. If the separator is not provided the , is used instead.

3.37.2Return Value

The split filter returns a list of strings computed by splitting the input string around matches of the separator.

3.38strip

The strip filter strips all HTML tags from its input and leaves only text.

{{ '<p><div>Test </div><span>text</span></p>' | strip }}

{# output: Test text #}

3.38.1Arguments

The strip filter has no arguments.

3.38.2Return Value

The strip filter retuns a string.

3.39temporalAmount

The temporalAmount filter is used to format an amount of time, such as "6 hours", "2 days" or "3 years and 2 months".

<p>This link will expire in {{ chargeFlowLevel.configuration.period | temporalAmount }}.</p>

Example with defaultValue:

<p>This link will expire in {{ chargeFlowLevel.configuration.period | temporalAmount("1 day") }}.</p>

3.39.1Arguments

defaultValue

The temporalAmount filter can accept a defaultValue argument which is returned if input date is null.

textWidth

The temporalAmount filter can accept a textFormat argument that controls the formatting of the output. The possible values are: WIDE (default, units are shown with full names), SHORT (units are shown with short abbreviations), NARROW (units are shown with one-letter abbreviations).

3.39.2Return Value

The temporalAmount filter retuns a string.

3.40time

The time filter is used to format date with only time information. The formatting takes current user’s locale into consideration while formatting.

{{ transaction.createdOn | time }}

If user’s locale is English USA (en_US), the output would be:

11:00:00 PM

If user’s locale is German (de_DE), the output would be:

23:00:00

3.40.1Arguments

defaultValue

The time filter can accept a defaultValue argument which is returned if input date is null.

3.40.2Return Value

The time filter retuns a string.

3.41title

The title filter will capitalize the first letter of each word.

{{ "article title" | title }}

The above example will output the following:

Article Title

3.41.1Arguments

The title filter has no arguments.

3.41.2Return Value

The title filter retuns a string.

3.42translate

The translate filter is used to support internationalization by translating input string into user’s language. In case you want to use the translations provided by the platform you should not touch the translation strings. However, you have the option to provide your own output but you will have to maintain it for every language yourself in that case.

 {{ 'Access Denied' | translate }}

If user’s language is English, the output would be:

 Access Denied

If user’s language is German, the output would be:

 Zugriff verweigert

The translate filter can accept a map of arguments which should be replaced by its placeholders in message. Message placeholder is written inside curly brackets ({…​}).

 {% set arguments = {'userName' : 'John'} %}

 {{ 'Hello {userName}' | translate(arguments) }}

 {# output: 'Hello John' #}

All messages in twig templates are fully translated for supported languages. Changing the message in twig template If you do not change messages or use the same messages which are filtered with translate filter, you will benefit from having everything automatically localized.

Note

All messages are fully translated in languages we currently support.

In case you want to customize translated messages and provide your own translations, you can achieve this by editing desired twig template using resource editor under Space > Resources > Editor. Editing of resource is bound to a context which consists of language and Space or Space View.

Resource Editor
Figure 1. Resource Editor

At the upper-left corner of the resource editor you can select desired Space, Space View and Language, and click to open a resource in context. Opening will automatically create new resource for the current context. When you are finished with customization, click save button to persist all changes.

3.42.1Arguments

arguments

The map of arguments which should be replaced in a string.

3.42.2Return Value

The translate filter returns a string.

3.43translatePlural

Sometimes there is a need to translate different messages based on a number. Typically, translations for singular and plural differ and that’s where the translatePlural filter can help. The translatePlural can be used to translate singular and plural messages. The input string of translatePlural filter is a singular message. The plural message is passed as a pluralText argument.

{% set pluralArguments = {'numberOfApples' : appleTree.numberOfApples} %}
{{ 'There is one apple on the tree.' | translatePlural('There are {numberOfApples} apples on the tree.', appleTree.numberOfApples, pluralArguments) }}

Assuming that apple tree has 99 apples, the above example would output:

There are 99 apples on the tree.

3.43.1Arguments

pluralText

The plural text, which is translated and returned as a result when numberOfPlurals is greater than 1.

numberOfPlurals

The number based on which the singular or plural text is selected for translation.

arguments:: arguments

The map of arguments which should be replaced in a translated string.

3.43.2Return Value

The translatePlural filter returns a string.

3.44trim

The trim filter strips whitespace from the beginning and end of an input string:

{{ "    This text has too much whitespace.    " | trim }}

The above example will output the following:

This text has too much whitespace.

3.44.1Arguments

The trim filter has no arguments.

3.44.2Return Value

The return value of trim filter is string.

3.45upper

The upper filter makes an entire string upper case.

{{ "this is a quiet sentence." | upper }}

The above example will output the following:

THIS IS A QUIET SENTENCE.

3.45.1Arguments

The upper filter has no arguments.

3.45.2Return Value

The return value of upper filter is string.

3.46urlencode

The urlencode filter translates an input string into application/x-www-form-urlencoded format using the UTF-8 encoding scheme.

Note

The URL encoding converts characters into a format that can be transmitted over the Internet.

{{ "This string is UTF-8 encoded using application/x-www-form-urlencoded scheme." | urlencode }}

The above example will output the following:

This+string+is+UTF-8+encoded+using+application%2Fx-www-form-urlencoded+scheme.

3.46.1Arguments

The urlencode filter has no arguments.

3.46.2Return Value

The return value of urlencode filter is string.

4Tags

4.1autoescape

The autoescape tag can be used to temporarily disable or re-enable the autoescaper, as well as change the escaping strategy for a portion of the template.

Whether automatic escaping is enabled or not, you can mark a section of a template to be escaped or not by using the autoescape tag:

{{ danger }} {# will be escaped by default #}
{% autoescape false %}
    {{ danger }} {# will not be escaped #}
{% endautoescape %}
{{ danger }} {# will use the "html" escaping strategy #}
{% autoescape "js" %}
    {{ danger }} {# will use the "js" escaping strategy #}
{% endautoescape %}

When automatic escaping is enabled everything is escaped by default except for values explicitly marked as safe. Those can be marked in the template by using the raw filter:

{% autoescape %}
    {{ safe_value|raw }}
{% endautoescape %}

See the escaping section for more details on how escaping works.

4.2block

The block tag provides a way to change how a certain part of a template is rendered but it does not interfere in any way with the logic around it. The blocks are mainly used for inheritance and act as placeholders and replacements at the same time.

The block tag is immediately followed by the name of the block. This name will be the same name a child template uses to override it. The endblock tag can optionally contain the block’s name for readability. A simple definition of a block with the name title would look like this:

{% block title %}
     ...
{% endblock title %}
Note

Block names should consist of alphanumeric characters, and underscores. Dashes are not permitted.

Let’s take the following example to illustrate how a block works and more importantly, how it does not work:

base.twig
{% for post in posts %}
    {% block post %}
        <h1>{{ post.title }}</h1>
        <p>{{ post.body }}</p>
    {% endblock %}
{% endfor %}

If you render this template, the result would be exactly the same with or without the block tag. The block inside the for loop is just a way to make it overridable by a child template:

child.twig
{% extends './base.twig' %}

{% block post %}
    <article>
        <header>{{ post.title }}</header>
        <section>{{ post.text }}</section>
    </article>
{% endblock %}

Now, when rendering the child template, the loop is going to use the block defined in the child template instead of the one defined in the base one.

Note

A child template should not have any content outside of blocks. A child template is only used to override blocks of a parent template.

The executed template is then equivalent to the following one:

{% for post in posts %}
    <article>
        <header>{{ post.title }}</header>
        <section>{{ post.text }}</section>
    </article>
{% endfor %}

Let’s take another example: a block included within an if statement:

{% if posts is empty %}
    {% block head %}
        {{ parent() }}

        <meta name="robots" content="noindex, follow">
    {% endblock head %}
{% endif %}

Contrary to what you might think, this template does not define a block conditionally, it just makes overridable, by a child template, the output of what will be rendered when the condition is true.

If you want the output to be displayed conditionally, use the following instead:

{% block head %}
    {{ parent() }}

    {% if posts is empty %}
        <meta name="robots" content="noindex, follow">
    {% endif %}
{% endblock head %}

4.3extends

The extends tag allows to extend a twig template from another one in order to modify it by changing or adding features. By extending a parent template, a child template inherits all content of the parent template. This allows a child template to customize the parts of the parent template. To better understande the concept, let’s define a parent template which we will call base.twig:

base.twig
<html>
    <head>
    	<title>{% block title %} {% endblock %}</title>
    </head>
    <body>
    	<div id="content">
    	     {% block content %}
    	     Default content goes here.
    	     {% endblock %}
    	</div>

    	<div id="footer">
    	     {% block footer %}
    	     Default footer content
    	     {% endblock %}
    	</div>
    </body>
</html>

In this example, the block tags define three blocks (title, content and footer) that child templates can override or fill in.

All the block tag does is to tell the template engine that a child template may override those parts of the template.

A child template might look like this:

child.twig
{% extends './base.twig' %}

{% block title %} Home {% endblock %}

{% block content %}
    Home page content.
{% endblock %}

The extends tag is the key here, and it tells the template engine that this template inherits everything from parent template. When the template system evaluates this template, it first locates the parent. The extends tag must be the first tag in the template.

There is no limit to how long of an inheritance chain you can create, i.e. a child template can itself have a child template. A lot of potential comes from this fact because you can create a hierarchy of templates to minimize how much content you have to write on the lower levels.

Note that since the child template doesn’t define the footer block, the value from the parent template is used instead.

You can’t define multiple block tags with the same name in the same template. This limitation exists because a block tag works in "both" directions. That is, a block tag doesn’t just provide a hole to fill - it also defines the content that fills the hole in the parent. If there were two block tags with the same name in a template, that template’s parent wouldn’t know which one of the blocks' content to use.

<html>
    <head>
    	<title> Home </title>
    </head>
    <body>
    	<div id="content">
    	     Home page content.
    	</div>

    	<div id="footer">
    	     Default footer content
    	</div>
    </body>
</html>

4.4filter

The filter tag allow you to apply regular filters on a block of template data. Just wrap the code in the special filter section:

{% filter upper %}
    This text becomes uppercase
{% endfilter %}

You can also chain filters:

{% filter lower|escape %}
    <strong>SOME TEXT</strong>
{% endfilter %}

{# output: "&lt;strong&gt;some text&lt;/strong&gt;" #}

4.5for

The for tag is used to iterate through arrays, lists, collections as well as maps.

{% for user in users %}
    {{ user.name }} lives in {{ user.city }}.
{% endfor %}

Inside of a for loop block you can access some special variables:

loop.index

The zero-based current iteration of the loop.

loop.length

The size of the collection we are iterating over.

{% for user in users %}
    {{ loop.index }}. {{ user.name }}
{% endfor %}

The for tag also provides a convenient way to check if the iterable object is empty with the included else tag.

{% for user in users %}
   {{ user.name }} lives in {{ user.city }}.
{% else %}
    There are no users to display.
{% endfor %}

Iterating over maps can be done like so:

{% for entry in map %}
    {{ entry.key }} - {{ entry.value }}
{% endfor %}

4.6if

The if tag can be used to change the flow of template rendering, depending on the result of an expression.

{% if users is empty %}
    There are no users.
{% elseif users.length == 1 %}
    There is only one user.
{% else %}
    There are many users.
{% endif %}
{% if temperature > 18 and temperature < 27 %}
    <p>It's a nice day for a walk in the park.</p>
{% endif %}
{% if not user.subscribed %}
    <p>You are not subscribed to our mailing list.</p>
{% endif %}

4.7include

The include tag allows you to insert the rendered output of another template directly into the current template.

{% include 'header.twig' %}
    Body content goes here.
{% include 'footer.twig' %}

The included template will have access to the same variables that the current template does. You can add additional variables, to the included template, by passing them after the with keyword:

{% include 'template.twig' with {'foo': 'bar', 'baz' : true} %}

4.8set

The set tag allows to define a variable in the current context, whether it currently exists or not.

{% set header = 'Test Page' %}

{{ header }}

{# output: 'Test Page' #}

5Tests

Tests are used in combination with test operators to produce a logical result.

5.1defined

The defined checks if a variable is defined in the current context. The defined test works with variable names and attributes on variable names.

{% if user is defined %}
	{% if user.dateOfBirth is defined %}
    	    ...
	{% endif %}
{% endif %}

5.2empty

The empty test checks if a variable is empty. A variable is empty if it is null, an empty string, an empty collection, or an empty map.

{% if user.email is not empty %}
    ...
{% endif %}
{% set name = '' %}

{{ name is empty }}

{# output: true #}

5.3even

The even test checks if a number is even.

{% if 2 is even %}
    ...
{% endif %}

5.4existing

The existing test checks if a resource path exists.

{# evaluates to true if the resource path exists #}
{{ resourcePath is existing }}

5.5iterable

The iterable test checks if a variable is capable of being iterated.

Note

Collections, lists and maps are all iterable.

{# evaluates to true if the users variable is iterable #}
{% if users is iterable %}
    {% for user in users %}
        Hello {{ user }}!
    {% endfor %}
{% else %}
    {# users is probably a string #}
    Hello {{ users }}!
{% endif %}

5.6map

The map test checks if a variable is an instance of a map data type.

Note

In computer science map is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears at most once in the collection.

{{ {"apple":"red", "banana":"yellow"} is map }}

{# output: true #}

5.7null

The null test checks if a variable is null.

Note

null value of a variable means that value of the variable is uninitialized.

{% set name = null %}

{{ name is null }}

{# output: true #}

5.8odd

The odd test checks if a number is odd.

{% set number = 3 %}

{{ number is odd }}

{# output: true #}

6Operators

6.1Arithmetic

An arithmetic operator takes numerical values as their operands and returns a single numerical value. All the regular math operators (+, -, /, %, *) are available for use within expression blocks. Order of operations applies to all operators.

{{ 2 + 2 / ( 10 % 3 ) * (8 - 1) }}

{# output: 16 #}

6.2Logical

Logical operators are typically used with logical values (true and false) or with expressions which return logical value.

The and and or operators are available to join boolean expressions.

6.2.1and

The and operator evaluates to true if the left and the right expression are both true.

{% if 2 is even and 3 is odd %}
    ...
{% endif %}

6.2.2or

The or operator evaluates to true if the left or the right expression is true.

{% if 2 is even or 2 is odd %}
    ...
{% endif %}

6.2.3not

The not operator negates a boolean expression.

{{ 3 is not even }}

{# result: true #}

6.3Comparison

A comparison operator compares its operands and returns a logical value based on whether the comparison is true. The operands can be numerical, string, logical, or object values.

The following comparison operators are available in any expression: ==, !=, <, >, <=, >=.

{{ 1 > 3 }}

{# output: false #}
Note

The equals can be used as an alias for == operator.

{{ 'Monkey' equals 'Dog' }}

{# output: false #}

6.4Containment

6.4.1contains

The contains operator can be used to determine if a collection, map, or array contains a particular item.

{{ ["apple", "pear", "banana"] contains "apple" }}

{# output: true #}

When using maps, the contains operator checks for an existing key.

{% set fruits = {"apple":"red", "banana":"yellow"} %}

{{ fruits contains "banana" }}

{# output: true #}

The contains operator can be used to look for multiple items at once:

{% set fruits = ["apple", "pear", "banana", "peach"] %}

{{ fruits contains ["apple", "peach"] }}

{# output: true #}

6.5Test

The test operators apply one of the test tags to a variable and produce a logical result.

6.5.1is

{% if 2 is even %}
    ...
{% endif %}

6.5.2is not

The result of the test tags can be negated by using the is not operator.

{% if number is not even %}
    {{ number }}
{% endif %}

6.6Other

6.6.1Concatenate

The ~ operator is used to concatenate two strings.

{% set greeting = 'Hello ' %}
{% set name = 'John' %}

{{ greeting ~ name }}

{# output: 'Hello John' #}

6.6.2Conditional (ternary) operator

The ?: is called ternary operator and takes three arguments. The syntax is condition ? expr1 : expr2, where condition is an expression which evaluates to true or false, and expr1 and expr2 are expressions of any type.

{% set number = -1 %}

{{ 'Number is ' ~ (number > 0 ? 'positiv' : 'negative') ~ '.' }}

{{ outputs: 'Number is negative.' #}