Personalization using Jinja

Lots of features in Exponea enable the use of personalization via jinja. This enables to replace text in various parts by calling customer attributes, catalog items, etc. Full jinja documentation can be found at http://jinja.pocoo.org/docs/dev/ and this guide summarizes some of the common examples. Some of the examples can also be found in personalization in e.g. email templates.

Uses

Jinja can be used for different use-cases, including:

  • calling user attributes and inserting these values to text. This enables to easily start the emails, etc. with customer's first name.
  • referencing catalogs, aggregates, reports or other features of Exponea in e.g. weblayers
  • creating scripts including conditions, cycles, filters, changing the format of displayed data, etc.

Syntax

In Exponea, most common Jinja uses include Jinja expressions, that are called using {{ .... }} tags, and statements, that are called using {% ... %} tags

Global variables in Jinja

Campaigns and Project have variables. Variables such as ID and name can be used for personalization in campaigns.

Project
Project variables are accessible through all campaigns (Scenario, Banner, Experiments, Tags)
{{ project['id'] }} - id of the project
{{ project['name] }} - name of the project
Scenario
{{ scenario['id'] }} - id of thescenario
{{ scenario['name'] }} - name of the scenario
Scenario Node, Email Campaign
{{ action['id'] }} - id of the action node in Scenario where the Jinja was executed
{{ action['name'] }} - name of the action node in Scenario where the Jinja was execute or name of the email campaign
Banner
{{ banner['id'] }} - id of the banner
{{ banner['name'] }} - name of the banner
{{ banner['variant']['id'] }} - id of the variant
{{ banner['variant']['name'] }} - name of the variant
Experiments
{{ experiment['id'] }} - id of the experiment
{{ experiment['name'] }} - name of the experiment
{{ experiment['variant']['id'] }} - variant id of the experiment
{{ experiment['variant']['name'] }} - variant name of experiment
Tag manager
{{ tag['id'] }} - id of the tag
{{ tag['name'] }} - name of the tag

Expressions

Usually, statements are used when simply referrencing some parts of Exponea, with uses below. Basic syntax is usually {{ reference['attribute'] }}, however when the attribute consists of more words, the syntax has to be {{ reference["reference attribute"] }}

  • Customer attributes - Customer attributes will return the value that is stored in the customer profile for the specified attribute. Basic syntax is {{ customer['attribute'] }}
  • Event trigger attributes - When a scenario is triggered by an event, you can refer to its attributes using {{ event['attribute'] }}. Please note that always the keyword "event." has to be used, not the actual name of the event.
  • Webhook response - Basic syntax is {{ webhook['data'] }} or {{ webhook["JSON object key"] }}
  • Metrics - Referenced by {{ metrics["metric ID"] }}
  • Reports - It is possible to return a value from a report based on rows and columns. The syntax is {{ report_value_by_key("Report ID", "row value", "column value", metric order) }} . If you don't have columns or rows, you can skip the value. Metrics start counting from 0, and when you don't input any value, it will get first metric by default.
  • Catalog - A product from catalog can be retrieved by {{ catalogs["catalog name"].item_by_id(product_id) }}. To retrieve multiple products at once use {{ catalogs["catalog name"].items_by_id(list_of_ids) }}. Product attributes are then referenced by {{ item["catalog attribute]" }}. Please note that for this to work, you need to define item first e.g {{ set item = catalogs["Products"].item_by_id(1) }}
  • Catalog item - Product attributes are referenced by {{ item["catalog attribute]" }}. Please note that for this to work, you need to define item first e.g {{ set item = catalogs["catalog name"].item_by_id(product_id) }} or see below in statements.
  • Recommendation - Recommendations can be referenced by {{ recommendations("recommendation ID", number_of _products ) }} which will return list of products.
    To display recommended items you can loop through the returned array. Example: {%- set items = recommendations('0a1b2c3d4e5f6g7h8i9j0k', 5) %}
  • Recommendation items - Referenced by {{ item["catalog attribute]" }}. Please note that for this to work, you need to define "item" first, please see below in statements
  • Surveys -Referenced by {{ survey["survey name"] }}. This will generate a hyperlink
  • Unsubscribe link - Is generated by {{ consent.page }}. This will bring customers to the unsubscribe page where they can unsubscribe from separate campaign groups. In case the consent framework is not turn on, the link is referenced by {{ email.unsubscribe }}.
  • View in browser - Link that will display the email in the browser is generated by {{ email.view }}.
  • Other than that, it is possible to output some variables that were defined previously {{ variable }}
  • It is possible to use Math operators as well, such as +,-,*,/, however, the expression has to be within one tag, such as {{ 1+1 }}

Jinja references for metrics and reports are cached for 5 minutes before recalculated again by different customers.

Statements

Statements in Jinja are operators that can work with data in multiple ways. It allows you to, for example:

  • use conditions with following syntax (If, else if, else) {% if condition %}value{% elif condition2 %}value2{% else %}value3{% endif %} This will enable you to have e.g. call back values if someone has empty attribute.
  • use cycles, enabling you to repeat an action several times. This is useful when working with list attributes or JSONs. Syntax is {% for variable in array %} action {% endfor %}
  • using variables using {% set variable = value %}, which is used when referencing a catalog item.

It is also possible to modify the output of the statement using filters that are defined after pipe | separator. Below are possible uses of the filters

  • first, last, length
  • lower, upper
  • trim
  • json, from_json
  • from_timestamp('%y-%m-%d')
  • hash
  • b64encode, b64decode, urldecode, urlencode
  • round(value, precision=0, method='common')
    • common rounds either up or down
    • ceil always rounds up
    • floor always rounds down

These filters enable you to e.g. set an ID to lowercase email every time, ensuring that you will not generate multiple IDs (which are case sensitive) when customer decides to identify once with lowercase email and once with uppercase.

Use case examples

Don't execute an action for a specific customer

You can use the {% abort %} command which will stop executing code for a specific customer who meets the given conditions. For example, using {% abort %} in an email node in a scenario will prevent the email from sending and the scenario will not continue to consequent nodes (only for the specific customer). If used in an email, you will be able to see the abort runs in the scenarios test tab (when you hover over the email node). No event is tracked for abort for now. However, if you use the syntax {% abort: "Custom message" %}, the action will not only be aborted, but it will also add a campaign event with status aborted and the Custom message will be in the property message. The custom message can be any Jinja expression, so you are not restricted to only constants. Thereby, you can, for instance, propagate the reason why the action was aborted for a particular customer. Note that while the abort tag is also available in non-actions (conditions, wait nodes and limits), no event will be added even if reason is provided.

Lowercase email_id (in REST API request)

"email_id": {{ customer['email'] | lower | json }}

If doing JSON API requests, it may actually make more sense to build the request as a dictionary in jinja and serialize the whole thing.

{{ {"customer": {"email_id": customer['email'] | lower}, "other_key": 42} | json }}

Get email domain

{{ customer.email.split('@') | last }}

Calculate age of customer

when customer.date_of_birth is string in format 2017-01-31
calculated age has 1 year tolerance (does not count with months and days)

age = {{ time | from_timestamp('%Y') -  customer['date_of_birth'].split('-')[0] }}

Count cookies

cookie_cnt = {{ (1 if customer_ids.cookie is string else customer_ids.cookie | length) if customer_ids.cookie else 0 }}

Having a fallback if a customer attribute doesn't have a value

{% if customer.first_name %} {{customer['first_name']}} {% else%}Sir/madam{% endif %}

Outputting multiple catalog values for a list of item IDs

This is usually used in cart abandonment, when you have a list of items in a customer aggregate, where it is taken from last cart update of customer. If you work with JSON and not a simple list, you need to further specify product when setting item.

<pre class="EnlighterJSRAW" data-enlighter-language="python">
{% set items = catalogs["catalog name"].items_by_id(list_of_ids) %}
{% for item in items %}
  {{ item['name'] }} {{item['price']}} 
  &lt;img src="{{item['image_source']}}"/&gt; 
{% endfor %}
</pre>

Updated 8 days ago

Personalization using Jinja


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.