
Tags are jinjava-based functions. They enable easier access to some jinjava expressions, with additional or alternative logic tailored to the needs of our clients.


<div class="admonition admonition-tip"><div class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /></svg></div><div class="admonition-body"><div class="admonition-content">

If you use Visual Studio Code as your editor, you can use code snippets to speed up working with inserts.  
You can find the snippets in our Github repository: [https://github.com/Synerise/jinja-code-snippet](https://github.com/Synerise/jinja-code-snippet)

</div></div></div>


## Tag delimiters

They can use two types of delimiters:
- `{% %}` - available in all tags.
- `{%- -%}` - available in tags that have an opening and closing statement. Unnecessary whitespace inside the tags is removed. Using these delimiters where possible is recommended for improved performance.

**Example**:  

<div class="content-tabs" data-tab-group="tabgrp-10">
<div class="tab-buttons"><button class="tab-button" data-tab-id="tabgrp-10-0" data-tab-group="tabgrp-10" data-tab-active="true">{%- -%}</button><button class="tab-button" data-tab-id="tabgrp-10-1" data-tab-group="tabgrp-10">{% %}</button></div>

<div class="tab-panel" data-tab-id="tabgrp-10-0" data-tab-group="tabgrp-10" data-tab-active="true">

Input:

<pre><code class="language-jinja">{% set b = 'I remove the whitespace' %}

{%- if b -%}

{{b}}

End of IF
{%- endif -%}</code></pre>


Data sent to the browser:

<pre><code class="language-plaintext">"I remove the whitespace\nEnd of IF"</code></pre>

</div>

<div class="tab-panel" data-tab-id="tabgrp-10-1" data-tab-group="tabgrp-10">

Input:

<pre><code class="language-jinja">{% set a = 'I keep the whitespace' %}

{% if a %}

{{a}}

End of IF
{% endif %}</code></pre>


Data sent to the browser:

<pre><code class="language-plaintext">"\n\nI keep the whitespace\nEnd of IF\n"</code></pre>

</div>
</div>


## Append

You can use `do append` to add an item to a list.

**Syntax:**

<pre><code class="language-jinja">{% do listname.append('string')}</code></pre>


**Example:**  
This example uses `do.append` and [`loop.index`](#loop-variables) to iterate over a list of items and pull corresponding values from another list to create an array of objects with values from both lists.


<pre><code class="language-jinja">{#  List of items:  #}
{% set itemsArray = ['item1','item2','item3'] %}
{#  List of prices for the items:  #}
{% set pricesArray = ['item1_price','item2_price','item3_price'] %}
{#  Empty array to fill with objects:  #}
{% set arrayWithItemsAndPrices = [] %}

{#  Start iterating over itemsArray  #}
{%- for item in itemsArray -%}
    {#  Set variable to store index of the current iteration:  #}
    {% set index=loop.index0 %}
    {#  Append object to the array  #}
    {% do arrayWithItemsAndPrices.append({
        item: item,
        price: pricesArray[index], 
        index: index 
        })
    %}
{%- endfor -%}</code></pre>


In the object:
- `item` is the current item from `itemsArray`,
- `price` is pulled from the corresponding index from `pricesArray`,
- `index` is the current iteration

**Result:**  
The `arrayWithItemsAndPrices` array is the following:

<pre><code class="language-json">[
    {item=item1, price=item1_price, index=0},
    {item=item2, price=item2_price, index=1},
    {item=item3, price=item3_price, index=2}
]</code></pre>



<div class="admonition admonition-tip"><div class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /></svg></div><div class="admonition-body"><div class="admonition-content">

The items and prices could be inserted from an aggregate.

</div></div></div>

## AutoEscape

Autoescape the tag's contents.


<pre><code class="language-jinja">{%- autoescape -%}
    {# Code to escape #}
{%- endautoescape -%}</code></pre>


## Call

In some cases, it can be useful to pass a [macro](/developers/inserts/tag#macro) to another macro. For this purpose, you can use the special call block.

This is a simple dialog rendered by using a macro and a call block:


<pre><code class="language-jinja">{%- macro dump_users(users) -%}
    &lt;ul&gt;
    {%- for user in users -%}
        &lt;li&gt;
            &lt;p&gt;{{ user.username|e }}&lt;/p&gt;
            {{ caller(user) }}
        &lt;/li&gt;
    {%- endfor -%}
    &lt;/ul&gt;
{%- endmacro -%}

{%- call(user) dump_users(list_of_user) -%}
    &lt;dl&gt;
        &lt;dl&gt;Realname&lt;/dl&gt;
        &lt;dd&gt;{{ user.realname|e }}&lt;/dd&gt;
        &lt;dl&gt;Description&lt;/dl&gt;
        &lt;dd&gt;{{ user.description }}&lt;/dd&gt;
    &lt;/dl&gt;
{%- endcall -%}</code></pre>


## Cycle

The cycle tag can be used within a for loop to cycle through a series of string values and print them with each iteration.

**Parameters:**

| Type | Required | Description |
| :--- | :--- | :--- |
| list | yes | A comma-separated list of strings to print with each iteration. The list will repeat if there are more iterations than string parameter values. |

In the example below, the classes `odd` and `even` are applied to posts in a listing:


<pre><code class="language-jinja">{%- set contents = ['content 1', 'conent 2', 'content 3', 'content 4'] -%}

{%- for content in contents -%}
    &lt;div class="post-item {% cycle 'odd','even' %}"&gt;
        Blog post content
    &lt;/div&gt;
{%- endfor -%}</code></pre>


Output:

<pre><code class="language-html">&lt;div class="post-item odd"&gt;
    Blog post content
&lt;/div&gt;&lt;div class="post-item even"&gt;
    Blog post content
&lt;/div&gt;&lt;div class="post-item odd"&gt;
    Blog post content
&lt;/div&gt;&lt;div class="post-item even"&gt;
    Blog post content
&lt;/div&gt;</code></pre>


## If, else if, else

Outputs inner content if expression evaluates to true, otherwise evaluates elif blocks, finally outputting the content of the else block present (if no elif block evaluated to true).


<pre><code class="language-jinja">{%- if number &lt;= 2 -%}
    Variable named number is less than or equal to 2.
{%- elif number &lt;= 4 -%}
    Variable named number is less than or equal to 4.
{%- elif number &lt;= 6 -%}
    Variable named number is less than or equal to 6.
{%- else -%}
    Variable named number is greater than 6.
{%- endif -%}</code></pre>


### Combining conditions

You can combine conditions with the following operators:
- `and` / `&&`
- `or` / `||`
- `not` / `!`

If a condition uses functions and includes spaces (such as in [tests](/developers/inserts/exptest)), it may be evaluated incorrectly or stop the rendering. For best results, we recommend using brackets with all conditions.

**Examples**:


<pre><code class="language-jinja">{%- if (2 == 2) and (3 == 3) -%}
    {# recommended #}
{%- endif -%}

{%- if (5 is divisibleby 5) and (2 == 2) -%}
    {# correct, recommended #}
{%- endif -%}

{% if (not(5 is divisibleby 4)) and (2 == 2) %}
    {# correct, recommended #}
{% endif %}

{%- if 5 is divisibleby 5 and 2 == 2 -%}
    {# INCORRECT #}
{%- endif -%}

{%- if 2 == 2 and 3 == 3 -%}
    {# NOT recommended #}
{%- endif -%}</code></pre>


## For

Outputs the inner content for each item in the given iterable.

**Examples**:

<div class="content-tabs" data-tab-group="tabgrp-11">
<div class="tab-buttons"><button class="tab-button" data-tab-id="tabgrp-11-0" data-tab-group="tabgrp-11" data-tab-active="true">List</button><button class="tab-button" data-tab-id="tabgrp-11-1" data-tab-group="tabgrp-11">Object properties</button><button class="tab-button" data-tab-id="tabgrp-11-2" data-tab-group="tabgrp-11">Object as dict</button></div>

<div class="tab-panel" data-tab-id="tabgrp-11-0" data-tab-group="tabgrp-11" data-tab-active="true">

Iterating over a list.

<pre><code class="language-jinja">{% set names = ["John", "Kate", "Bob"] %}

{%- for item in names -%}
    Hello, {{ item }}!
{%- endfor -%}</code></pre>

</div>

<div class="tab-panel" data-tab-id="tabgrp-11-1" data-tab-group="tabgrp-11">

Iterating over object properties.

<pre><code class="language-jinja">{%- set exampleProduct = {'size': 12, 'title': 'Item', 'color': 'blue'} -%}
{%- for key, value in exampleProduct.items() -%}
    {{ value }}{% if not loop.last %} {% endif %}
{%- endfor -%}</code></pre>


Output:

<pre><code class="language-LANG">12 Item blue</code></pre>

</div>

<div class="tab-panel" data-tab-id="tabgrp-11-2" data-tab-group="tabgrp-11">

By using the `items()` function, you can treat an object like a dict.

<pre><code class="language-jinja">{% set exampleProduct = {'size':12,'title':'Item', 'color': ['red','blue','yellow']} %}
{%- for key, value in exampleProduct.items() -%}
{{ key }} : {{ value }}&lt;br&gt;
{%- endfor -%}</code></pre>

Output:

<pre><code class="language-LANG">size : 12
title : Item
color : [red, blue, yellow]</code></pre>

</div>
</div>


### Loop variables
Inside the `for` loop, you can access special variables.

| col1 | col2 |
| --- | --- |
| `loop.index` | The current iteration, first iteration is `1` |
| `loop.index0` | The current iteration, first iteration is `0` |
| `loop.revindex` | Iterations until end of loop, last iteration is `1` |
| `loop.revindex0` | Iterations until end of loop, last iteration is `0` |
| `loop.first` | `true` if this is the first iteration |
| `loop.last` | `true` if this is the last iteration |
| `loop.length` | Total number of items in the loop |
| `loop.cycle()` | Helper function for cycling, see example below the table |
| `loop.depth` | The depth of the current iteration in a recursive loop, starting at `1` |
| `loop.depth0` | The depth of the current iteration in a recursive loop, starting at `0` |

#### Example
**Input:**

<pre><code class="language-jinja">{%- set array = ["q","w","e","r","t"] -%}
{%- for item in array -%}
Item: {{ item }}
&lt;br&gt;
Index: {{ loop.index }}
&lt;br&gt;
Revindex: {{ loop.revindex }}
&lt;br&gt;
Cycle: {{ loop.cycle('foo','bar','baz') }}
&lt;br&gt;
{%- endfor -%}</code></pre>


**Output:**

<pre><code class="language-html">Item: q
Index: 1
Revindex: 5
Cycle: foo

Item: w
Index: 2
Revindex: 4
Cycle: bar

Item: e
Index: 3
Revindex: 3
Cycle: baz

Item: r
Index: 4
Revindex: 2
Cycle: foo

Item: t
Index: 5
Revindex: 1
Cycle: bar</code></pre>


## Get

See ["Object properties" in "Insert usage"](/developers/inserts/insert-usage#object-properties).


## Ifchanged

Outputs the tag contents if the given variable has changed since a prior invocation of this tag.


<pre><code class="language-jinja">{%- ifchanged variable -%}
    {#  Code to execute if the variable has changed  #}
{%- endifchanged -%}</code></pre>


## Intersect

Returns the common element of two arrays.

**Example**:  

<pre><code class="language-jinja">{%- set array1 = ["apple", "banana", "cherry","kiwis"] -%}
{%- set array2 = ["pear", "banana", "kiwi"] -%}

{%- set common = array1|intersect(array2) -%}

{{common}}</code></pre>


Output:

<pre><code class="language-LANG">['banana']</code></pre>


## Macro

Macros allow you to print multiple statements with a dynamic value or values.

Basic macro syntax:


<pre><code class="language-jinja">{#  Defining the macro  #}
{%- macro name_of_macro(argument_name, argument_name2) -%}
    {{ argument_name }}
    {{ argument_name2 }}
{%- endmacro -%}

{#  Calling the macro  #}
{{ name_of_macro("value to pass to argument 1", "value to pass to argument 2") }}</code></pre>


Example of a macro used to print CSS3 properties with the various vendor prefixes.


<pre><code class="language-jinja">{%- macro trans(value) -%}
    -webkit-transition: {{value}};
    -moz-transition: {{value}};
    -o-transition: {{value}};
    -ms-transition: {{value}};
    transition: {{value}};
{%- endmacro -%}</code></pre>


The macro can then be called like a function. The macro is printed for anchor tags in CSS.


<pre><code class="language-jinja">a { {{ trans("all .2s ease-in-out") }} }</code></pre>


## Print

Echoes the result of the expression.

**Examples:**

<pre><code class="language-jinja">{% set string_to_echo = "Print me" %}

{% print string_to_echo %}</code></pre>



<pre><code class="language-jinja">{% print -65|abs %}</code></pre>


## Range

Generates an array of integers. The array can't be longer than 1000 items.


<pre><code class="language-jinja">range(start,stop,step)</code></pre>


| Parameter | Required | Default | Description |
| --- | --- | --- | --- |
| start | no | `0` | The first value in the array. |
| stop | yes | n/a | The limit at which the array ends. The value of the limit is excluded from the array. |
| step | no | `1` | The increment between items. Can be negative. |

**Examples**:  

Default start and step:

<pre><code class="language-jinja">{% set foo=range(5) %}
{{ foo }}

OUTPUT:
[0, 1, 2, 3, 4]</code></pre>


Start defined, step default:

<pre><code class="language-jinja">{% set foo=range(2,10) %}
{{foo}}

OUTPUT:
[2, 3, 4, 5, 6, 7, 8, 9]</code></pre>


Defined start and step. The value of stop isn't included in the array.

<pre><code class="language-jinja">{% set foo=range(2,10,2) %}
{{foo}}

OUTPUT:
[2, 4, 6, 8]</code></pre>


Negative increment. The value of stop isn't included in the array. In this case, start must be higher than stop!

<pre><code class="language-jinja">{% set foo=range(10,2,-2) %}
{{foo}}

OUTPUT:
[10, 8, 6, 4]</code></pre>


## Raw

Processes all inner expressions as plain text.


<div class="admonition admonition-note"><div class="admonition-icon"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg></div><div class="admonition-body"><div class="admonition-content">

In this insert, use the delimiters without a dash  (`{% %}`). Adding the dashes (`{%- -%}`) may break the output.

</div></div></div>



<pre><code class="language-jinja">{% raw %}
    The personalization token for a contact's first name is {{ contact.firstname }}
{% endraw %}</code></pre>


## Set

Assigns the value or result of a statement to a variable.

**Basic syntax:**

<pre><code class="language-jinja">{% set variableName = variableValue %}</code></pre>


The value can be a string, a number, a boolean, or a sequence.

**Example:**

Set a variable and print the variable in an expression:


<pre><code class="language-jinja">{% set primaryColor = "#F7761F" %}

{{ primaryColor }}</code></pre>


You can combine multiple values or variables into a sequence variable.


<pre><code class="language-jinja">{% set var_one = "String 1" %}

{% set var_two = "String 2" %}

{% set sequence = [var_one, var_two] %}</code></pre>


## Try/catch


The try/catch syntax can be used to create a fallback mechanism for Jinjava that can't be processed, such as referencing an attribute that doesn't exist.

You can only include one catch statement, but you can nest another try/catch blocks inside it (see examples below).


<div class="content-tabs" data-tab-group="tabgrp-12">
<div class="tab-buttons"><button class="tab-button" data-tab-id="tabgrp-12-0" data-tab-group="tabgrp-12" data-tab-active="true">Example</button><button class="tab-button" data-tab-id="tabgrp-12-1" data-tab-group="tabgrp-12">Nesting example</button><button class="tab-button" data-tab-id="tabgrp-12-2" data-tab-group="tabgrp-12">Incorrect Jinjava</button></div>

<div class="tab-panel" data-tab-id="tabgrp-12-0" data-tab-group="tabgrp-12" data-tab-active="true">

In this example, the Jinjava in the `try/catch` block is correct, but references a variable that doesn't exist. The code from the `catch` statement is executed.

<pre><code class="language-jinja">{% try %}
{{ thisVariableDoesntExist }}
{% catch %}
I didn't find the variable!
{% endtry %}</code></pre>


OUTPUT:
```
I didn't find the variable!
```

</div>

<div class="tab-panel" data-tab-id="tabgrp-12-1" data-tab-group="tabgrp-12">

Each block can only include one `catch` statement, but you can nest blocks.

<pre><code class="language-jinja">{% try %}
{% customer thisParamDoesntExist %}
{% catch %}
    {% try %}
    {{ someVariableThatDoesntExist }}
    {% catch %}
    I didn't find the other variable either!
    {% endtry %}
{% endtry %}</code></pre>


OUTPUT:
```
I didn't find the other variable either!
```

</div>

<div class="tab-panel" data-tab-id="tabgrp-12-2" data-tab-group="tabgrp-12">

In this example, the Jinjava fails to render entirely because of a syntax error in the `try` statement (missing closing bracket).

<div class="highlight-code-block" data-hl-lines="2">
<pre><code class="language-jinja">{% try %}
{{ foo }
{% catch %}
...
{% endtry %}</code></pre>
</div>


OUTPUT:  
No output, Jinjava rendering failed.

</div>
</div>


The following table explains the behavior of the block in some common scenarios.
| Scenario | Result |
| --- | --- |
| Variable doesn't exist | catch |
| Syntax error in `try` or `catch` statement | Rendering fails |
| [Profile](/developers/inserts/insert-usage#customer-attributes) attribute with no value in the context profile | catch |
| Profile attribute doesn't exist at all in the database | catch |
| [Aggregate](/developers/inserts/insert-usage#aggregates) that doesn't exist or returns no value | catch |
| [Expression](/developers/inserts/insert-usage#expressions) doesn't exist | catch |
| Expression exists, returns `null` | try |
| Mathematical operation (other than `+`) on a null result from an expression.<br>Null is treated as a string. `+` results in concatenation. | Rendering fails |
| [Metric](/developers/inserts/insert-usage#metrics) doesn't exist | catch |
| Metric exists, but required item context isn't provided | catch |
| [Catalog](/developers/inserts/insert-usage#catalogs)/column/item doesn't exist | catch |
| Catalog/column/item doesn't exist, but `allowEmpty=True` | try |
| [Recommendation](/developers/inserts/insert-usage#recommendations) doesn't exist | catch |
| Recommendation returns an error | catch |
| Recommendation in draft status | catch |
| Required context missing in recommendation | catch |
| Recommendation context references item that doesn't exist | catch |
| [Voucher pool](/developers/inserts/insert-usage#code-pools) doesn't exist or expired | catch |
| No available vouchers in pool | catch |
| [{% terminate %}](/developers/inserts/insert-usage#stopping-communication-from-rendering) function in `try` statement | Rendering fails<sup>1</sup> |
| Reference to a function that doesn't exist | Rendering fails |
| `try` statement is empty | try (returns empty string) |
| `try` statement fails, but `catch` doesn't exist/is empty | Empty string |
| `catch` references a variable set in `try` | Rendering fails (variable is local to `try`, `catch` is sibling) |
| `try` references a variable set in an ancestor | try (variables are inherited) |
| Error in `catch` statement | Rendering fails |
| Type error, such as a mathematical operation on a string | Rendering fails |
| Illegal characters in variable names | Rendering fails |

<sup>1</sup> In certain situations, such as placing the terminate function inside another function, the terminate function is processed as normal and the catch statement is rendered.


## Unless

Unless is a conditional just like 'if', but works on an inverse logic.


<pre><code class="language-jinja">{%- unless x &lt; 0 -%}
    x is greater than zero
{%- endunless -%}</code></pre>


## Update

Creates or updates the properties of an object.

**Example**:

<pre><code class="language-jinja">{% set product = {'category':'sneakers'} %}

Initial object: {{product}}
&lt;br&gt;
{% set colorData = {'color':'red','size': 8} %}
{% do product.update(colorData) %}
Added color and size: {{product}}
&lt;br&gt;
{% set newColorData = {'color':'blue'} %}
{% do product.update(newColorData) %}
Updated color: {{product}}</code></pre>


Output:

<pre><code class="language-plaintext">Initial object: {category=sneakers}
&lt;br&gt;
Added color and size: {category=sneakers, color=red, size=8}
&lt;br&gt;
Updated color: {category=sneakers, color=blue, size=8}</code></pre>
