Personalizing campaign content with Liquid
Overview
Ortto allows you to use Liquid template language in your email, SMS, and push notifications. This helps you personalize content by combining merge tags with Liquid syntax for dynamic messages.
What is a Merge tag? Merge tags let you customize content based on individual, organization, custom fields, or activity attributes.
Why use Liquid syntax? Liquid allows you to enhance your messages with logic (such as if statements) and various filters to adjust merge tag values. This means you can include specific customer data and create more engaging and relevant content.
Learn more about control flows and operators.
Where can you use Liquid syntax? You can use Liquid syntax in the content sections of your email and SMS campaigns, including those within playbook and journey campaigns.
NOTE: Ortto only supports Liquid syntax in lower case and so merge tags must be written in lower case to function correctly.
IMPORTANT: Activity and attribute merge tags in Liquid only pull data from the last 30 days. If an activity is older than 30 days, the Liquid statement won’t work. To keep data beyond this timeframe, consider saving key activity attributes as person fields for long-term access.
About merge tags and Liquid syntax
Double curly braces (objects)
- Items contained in double curly braces will produce an output of the specified object and value. For example:
EX: The below liquid statement will output the first name (value) of the person (object) receiving the message:
{{ people.first-name }}
Single curly braces (delimiters)
- Single curly braces with percentage symbols (delimiters) are used for containing the logic that determines what content is visible, and won’t produce an output.
EX: The below statement will show content placed after the braces only to people who have ordered once from your Shopify store.
{% if activity.shopify.ordered-product.quantity == 1 %}
- Items in curly brace percentage delimiters that contain statements such as if need to have a terminating statement to be valid. That is, a statement beginning
{% if …}
will need to have a terminating statement such as{% endif %}
located where you want theif
condition to end. - If you start writing a condition that is contained in curly brace percentage delimiters and you add a merge tag to the statement, the merge tag will be inserted contained within double curly braces. You’ll need to delete this set of double curly braces and leave the merge tag object and value.
EX: Adding a merge tag to {% if %}
will result in {% if {{ people.city }} %}
but this is not valid. Instead, you would need to remove the double curly braces to complete the statement:
% if people.city == 'London' %}
Operators
Operators are used to determine your statement logic. Ortto supports the following operators:
Operator
Description
==
equals
!=
does not equal
>
greater than
<
less than
>=
greater than or equal to
⇐
less than or equal to
or
assesses whether the boolean (true/false) value of one or more merge tags is
true
and
assesses whether the boolean (true/false) values of all merge tags are
true
contains
checks for the presence of a string or substring (part of a string), usually a merge tag’s value
- Operators can be used to determine the values by which you wish to control the message content.
EX: Using the statement {% if people.city == 'London' %}
will determine that only people whose city value is London will see the subsequent content.
Alternatively, you might want to show a coupon to only those who are subscribed and have made at least 1 Shopify purchase. You would achieve this with the following statement: {% if people.email-permission == 'yes' and activity.shopify.ordered-product.quantity >= 1 %}
Determine the Liquid syntax in email and SMS messages
To add dynamic content and logic with merge tags in your email, SMS, and push notifications, you’ll need to use the raw Liquid syntax for those merge tags.
If Liquid can’t find a value for a merge tag or there’s a typo, it won’t display anything. To ensure a fallback is used, use the default field option when inserting merge tags or add the | default:
filter.
- Learn more about default filters.
NOTE: An object not found error can occur when using Liquid with a default value if the default value is missing quotation marks (""
or ''
). Following the rule of adding quotes based on whether your content includes an apostrophe, wrapping your content in single quotes (''
) should resolve the issue.

TIP: To display percentage fields in Liquid, divide the value by 10 using {{ people.custom-field | divided_by: 10 }}
.
Ortto stores percentages as decimals multiplied by 1000, so 50% is stored as 0.50. Use the above format to display 50% correctly in a campaign.
- When using Liquid syntax with strings which contain apostrophes (such as don’t), it’s recommended to wrap the whole string in double quotes to avoid syntax errors. Single quotes can conflict with apostrophes inside the string, leading to parsing issues.
EX: In the example below, the double quotes around the string allow the apostrophe in don't to be processed without causing a syntax error.
{{ people.external-id | default: "Oh no! Looks like you don't have a member number. Please contact support@example.com for assistance." }}
Use Liquid in email messages
You can view and edit the Liquid syntax for merge tags when creating an email message, in the email content page.
- Learn more about using liquid in email messages.
Use Liquid in SMS messages
You can use Liquid syntax for merge tags when creating an SMS message, in the SMS content page.
- Learn more about using liquid in SMS.
Use Liquid in push notifications
You can use Liquid syntax for merge tags when creating push notification, in the push content page.
- Learn more about using liquid in push notifications.
Translate campaign content with Liquid
Email message language translation is performed by adding Liquid syntax in the content step when creating an email.
NOTE: Ortto does not translate message content for you. You’ll need to write the text in the appropriate language.
EX: An email campaign in both English and Spanish should have subject lines and message text written in both languages. Use liquid conditions to ensure English readers see the English text and Spanish readers see the Spanish text.
- There are a number of ways you can set language conditions. Learn more about how to display translated email message content.
Control flow tags
Liquid syntax supports control flow tags, which in combination with operators determine the conditions under which blocks of Liquid code (contained within the curly brace percentage delimiters) are executed.
As indicated in the Liquid documentation, Ortto supports the following sets of control flow tags:
if
,elsif
*,else
*, andendif
unless
andendunless
case
,when
,else
*, andendcase
* optional tags
Each end.
tag ends a control flow block (such as endif
).
EX: Simple if
block (where people.custom.special-offer is a custom boolean-type field with a value of true or false, and its value is evaluated as a Liquid syntax truthy).
{% if people.custom.special-offer %}
Bonus: for being a loyal customer, we'd like to offer you half off your next purchase. Use the coupon code LOVE to redeem this offer.
{% endif %}
EX: if
block with optional elsif
and else
tags:
{% if organization.employees > 50 %}
With a large organization like yours, communication is key.
{% elsif organization.employees > 5 %}
In small-to-medium businesses like yours, the key is balance.
{% else %}
In a micro-organization like yours, you need to save every dollar.
{% endif %}
EX: Unless
block (asking the recipient to visit your Twitter profile where there are two fields which mark the person as having done so; people.custom.twitter-ready or people.custom.clicks contains).
{% unless people.custom.twitter-ready == true and people.custom.clicks contains 'https://mytwitter.url' %}
Go check us out on Twitter!
{% endunless %}
Iteration tags
You can use iteration tags such as for
, cycle
and tablerow
to output data that is an array type (a collection of values).
For example, if you have a custom field named "Favorite brands" that is a multi-select type, with the values [nike, adidas, puma]
, you can output one of the values with:
{% for b in people.favorite-brands %} {{ b }} {% endfor %}
and the output will be
adidas
.You can also iterate on activities, such as if you want to send an email to a person who left items in their shopping cart without checking out:
Are you still interested in these items? {% for item in activity.shopify.abandoned-cart.line-items %} {{ item.name }} {% endfor %}
which will output the name of the item/s which the customer had in their abandoned cart.
Learn about using
for
to loop through a JSON object at Access JSON objects with Liquid.Variable tags
Liquid syntax also supports the ability to assign values to variables.
Using variables may be useful when creating your own email and SMS templates, when you might require more sophisticated handling of merge tag values.
Liquid variables available to use are:
assign
capture
increment
decrement
.NOTE: When declaring a variable in Ortto using a Liquid variable tag, you must begin the variable name with
var
so that Ortto can recognize it as a declared variable.For example, this declared variable named
cities
begins withvar
, and you want to join the values ofvarcities
withand
in your output:{% assign varcities = "London, New York" | split: ", " %} {{ varcities | join: " and " }}
to output
London and New York
.One way you could use a variable tag is to assign a variable with the value of
now
to determine the time (using the strftime syntax) you send the message (rather than when the recipient sees the message){% assign vartodaydate = 'now' | date: '%s' %} {% assign varexpiry = people.custom.expire-date | date: '%s' %} {% if varexpiry < vartodaydate %} Your subscription expired today {% endif %}
Filters
Ortto supports the use of all Liquid filters, where a filter is used to modify a merge tag’s number, string, or object value.
Learn more about Liquid filters.
Other Liquid syntax and tags
In addition to the tags mentioned above, Liquid syntax also supports the following additional features and tags, which may be useful in your email and SMS campaign messages.
Truthy and falsy
Truthy and falsy control flow tests on both boolean and non-boolean (true/false) data types, such as the simple
if
block example above.As another example, if you have a boolean custom field called
Is VIP
, then you can use{% if people.custom.is-vip %} VIP special content {% endif %}
to only show the content to your VIPs.
Or you could show content to people who have not yet verified their email in Shopify:
{% unless people.shopify.verified-email %} Please verify your Shopify email {% endunless %}
Whitespace control syntax
Whitespace control syntax is used to omit blank lines resulting from the processing of other Liquid syntax tags. This is achieved by adding a hyphen to one or both of your delimiters or double curly braces, e.g.
{%-
,{%- … -%}
, or-}}
This can be useful to ensure your text content is formatted correctly, where
Hey, {{ people.first-name | default: 'there' }} ! Thanks for subscribing!
will result in
Hey, Patricia ! Thanks for subscribing!
adding the whitespace control syntax will remove unwanted spaces
Hey, {{ people.first-name | default: 'there' -}} ! Thanks for subscribing!
to output
Hey, Patricia! Thanks for subscribing!
Display an image from an activity’s attribute
It is possible to display an image in a campaign’s email message, where this image is sourced from an activity’s attribute, whose value is a image URL.
For example, a custom activity called Booked trip consists of the following information and attributes:
Booked trip (name of activity) Trip name Destination Destination image (containing a valid image URL) Arrival date Departure dateAfter a customer complete’s their booking, you may want to send the customer a confirmation email message that displays all details of this activity’s attributes for the booked trip, including the destination image (above).
To display an image from an activity’s attribute in an email message for a playbook, journey or email campaign:
From your email message’s Content page, determine the Liquid syntax for the activity’s attribute (merge tag) that contains the image URL (e.g.activity.custom.booking-complete.destination-image
). Drag a new HTML box across to the email content editor, and click within this new HTML box (containing the text I’m a new HTML block) to reveal its CONTENT PROPERTIES on the right. Remove the existing HTML code and replace it with:<img src="{{ LIQUID-SYNTAX-FOR-YOUR-ACTIVITYS-ATTRIBUTE-WITH-IMAGE-URL }}">
ReplaceLIQUID-SYNTAX-FOR-YOUR-ACTIVITYS-ATTRIBUTE-WITH-IMAGE-URL
with Liquid syntax you generated in step 1 above.TIP: If the availability of a valid image URL for this activity’s attribute cannot be guaranteed, you can use Liquid syntax’s [default] filter to specify a fallback image, e.g.
{{ activity.custom.booking-complete.destination-image | default: 'my.cdn.url/image }}
The image may appear broken in the editor. However, if the image URL of the activity attribute is valid, the image will be displayed correctly when the email is sent. It is recommended that you send a few test email messages first before actually sending your email campaign and/or making this email live.
Tag support in liquid
Tags added to your contacts can be utilized in your Liquid syntax.
Learn more about tag support in liquid.Audience support in liquid
You can use the audiences that your contacts belong to in your Liquid syntax.
Learn more about audience support in liquid.