Fine-tune email message personalization with Liquid

Attentive’s dynamic content, like variables and dynamic links, allows you to personalize the emails you send for each subscriber. See Personalize your email with dynamic content for more about personalization.

Because Attentive uses the Liquid templating language for personalization, you can use Liquid variables (objects), conditional logic, and iterative logic to fine-tune your personalizations.

Overview

You can use Liquid to include variables and execute logic, like conditional if/else logic and iterative for logic, in your message:

If there are errors with Liquid code (e.g., a value is missing for a subscriber, the syntax is incorrect), Attentive doesn’t send the email if it’s a marketing message. However, transactional messages are always sent, even if subscriber values are missing or there are Liquid syntax errors.

Notes:

  • Whenever possible, we recommend using display conditions instead of Liquid templating. This reduces the possibility of syntax errors that may cause marketing emails to be dropped and transactional emails to have missing or unresolved values.
  • Always preview your emails before sending a campaign or turning on a journey.

Use Liquid objects and object properties

Liquid objects (or variables) are placeholders that store a value, which can be displayed in a message. For example, you can use the {{subscriber.firstName}} object/variable to display a subscriber’s actual first name in messages sent to them. See Personalize your email with dynamic content - Variables for a list of standard, non-custom Liquid objects in Attentive and instructions for adding them to your messages.

Follow these guidelines when adding and formatting non-standard Liquid objects in your emails:

  • Enclose Liquid objects in curly braces {{ }}.
  • Enclose object properties in single quotes ' '.
    • For example, if the property is VIP status: {{ % if subscriber.custom['VIP status'] == "VIP" }}
    • This formatting prevents issues if an object property contains spaces or if Liquid is embedded inside HTML tags with double quotes.
  • Don’t use single quotes for boolean values (more about booleans here).
    • For example, if the boolean value is true: {{ % if subscriber.custom['isVIP'] == true }}

You can use variables in any content block containing text (such as a paragraph block, title block, or list block) in the drag-and-drop email editor. You can also use them in HTML content blocks and in the HTML editor.

Use Liquid date objects

Liquid allows you to personalize messages with dates, which can be helpful for offer expiration, birthday messages, or subscription messages. You can reference these dates from custom attributes, custom event data, or Liquid's built-in now date object, which gets pulled in at time of send.

Attentive ingests dates in ISO 8601 format, but you may want to change the format to be more human-readable. When formatting dates, use the Liquid date filter, then bring in different parts of the date individually (day, month, year, time) or use preset date formats.

See the examples below for some common formats used on the now object.

Description Liquid code Output
DD/MM/YY {{ "now" | date: "%D" }} 09/06/24
Full date and time {{ "now" | date: "%c" }} Fri, Sept 06 10:15:00 2024
Day, Month DD {{ "now" | date: "%A, %B %e" }} Friday, September 6
12-Hour Time {{ "now" | date: "%I:%M %P" }} 10:15 am

Use conditional logic with Liquid

You can use Liquid to write conditional logic in your messages. Conditional logic (also called statements or tags) allows you to display content based on certain conditions being met. For example, if a subscriber’s favorite color is red, you can display one message, and if a subscriber’s favorite color is anything other than red, you can display a different message.

See Control flow (Shopify) for a more detailed guide about creating conditional logic with Liquid.

Note: In Attentive, you can only use conditional statements in HTML content blocks or in the HTML editor.

Syntax for conditional logic with subscriber attributes

Here are a few important guidelines for writing conditional logic with Liquid:

  • Wrap conditional logic in “Liquid tags,” denoted by curly brace percentage delimiters {% %}.
  • You can use as many if / elsif / else conditional statements as you need.
  • Always end conditional statements with an endif statement.

You can use the if, elsif, else, and endif tags to execute your use case.

if / elsif

The example below shows Liquid conditional logic that evaluates a custom attribute (favorite makeup product). If the if condition isn’t met, the logic proceeds to evaluate the else condition.

{% if subscriber.custom[‘favorite makeup product’] == “lipstick” %}

Check out Rihanna’s favorite lip picks for you!

{% else %}

Check out Rihanna’s top picks for you!

{% endif %}

In the example, if a subscriber’s favorite makeup product is lipstick, then the message will say: Check out Rihanna's favorite lip picks for you!. However, if a subscriber’s favorite makeup product is anything other than lipstick, then the message will say: Check out Rihanna's top picks for you!.

If you only want to evaluate whether something is true, you can omit == true. The example below shows conditional logic that evaluates whether a subscriber is a vip.

{% if subscriber.custom[‘vip’] %}

Hi, VIP customer!

{% endif %}

See the example below for conditional logic that uses if, elsif, and else conditions:

Liquid code Output
{% if subscriber.custom[‘which pets are you shopping for’] == “dog” %}

We hear you’re a dog-lover! Check out some great toys for your canine.

{% elsif subscriber.custom[‘which pets are you shopping for’] == “cat” %}

Shopping for your feline? Check out our great toy selection.

{% elsif subscriber.custom[‘which pets are you shopping for’] == “parakeet” %}

Chirp chirp! Spoil your parakeet with our new toys.

{% else %}

Check out some great toys for your pet!

{% endif %}

If the subscriber responds that they like dogs:

We hear you're a dog-lover! Check out some great toys for your canine.

If the subscriber responds that they like cats:

Shopping for your feline? Check out our great toy selection.

If the subscriber responds that they like parakeets:

Chirp chirp! Spoil your parakeet with our new toys.

If the subscriber responds with something other than dog, cat, or parakeet:

Check out some great toys for your pet!

Booleans

You can also use conditional logic with boolean properties (true and false). Like other variables, these come from either a custom attribute in the subscriber’s profile or the Custom Events API. Unlike other Liquid properties, however, you don’t need to enclose booleans in single quotes.

See the example below for logic that uses booleans to evaluate whether a subscriber custom attribute is true:

Liquid code Output
{% if subscriber.custom[‘responded to product survey’] == true %}

Thank you for being a loyal customer and for sharing your feedback with us! Use code BESTFRIEND10 for 10% off your next purchase.

{% else %}

Hey there, you still have 5 more days to complete our product survey. We’d love to hear from you!

{% endif %}

If customer filled out a product survey:

Thank you for being a loyal customer and for sharing your feedback with us! Use code BESTFRIEND10 for 10% off your next purchase.

If customer didn’t fill out the product survey:

Hey there, you still have 5 more days to complete our product survey. We'd love to hear from you!

Null values

Some APIs and integrations send object properties with null values, which generally means that a value isn’t present for an object. When possible, send booleans instead of null values or exclude them from the event object altogether.

If you must send null values, note the following:

  • Null values should be sent to our APIs without quotes:
    • { last_name: null }
    • { last_name: "NULL" }
  • if conditionals for null values will fail, and the Liquid code will be skipped.
  • If an undefined macro is referenced within a conditional clause (e.g., {% if myUndefinedMacro = 'LoyaltyId' %}), the message won’t be dropped. However, if it’s referenced to print (e.g., {{ myUndefinedMacro }}), the message will be dropped.
  • Attempting to display a null value in a message will cause errors:
    • Marketing emails will be dropped.
    • Transactional emails will be sent with errors, which usually appear as blank sections in the HTML.

Operators

You can use operators to evaluate object properties. Common operators include ==, which you can use in conditional statements to show or hide content based on certain criteria.

Other operators include the following:

Operator syntax Operator description
== equals
!= does not equal
> greater than
< less than
= greater than or equal to
<= less than or equal to
or condition A or condition B
and condition A and condition B
contains evaluates whether a string or array of strings contains a specific string

In the example below, the > operator is used to evaluate whether subscribers have spent more than $500. Subscribers who spend more than $500 receive a free gift, while subscribers who spend less than $500 get free shipping:

Liquid code Output
{% if subscriber.custom[‘total spend’] > 500}

It’s National Customer Day, and we want to thank you for being great! Use FREEGIFT at checkout for a special thank you from us.

{% else %}

It’s National Customer Day, and we want to thank you for being great! Use FREESHIPPING at checkout to get shipping for your next order on the house!

{% endif %}

If the subscriber has spent more than $500:

It's National Customer Day, and we want to thank you for being great! Use FREEGIFT at checkout for a special thank you from us.

If the subscriber has spent less than $500:

It's National Customer Day, and we want to thank you for being great! Use FREESHIPPING at checkout to get shipping for your next order on the house!

Notes:

  • Operators are evaluated from right to left.
  • Parentheses are not supported in Liquid. They’re evaluated as invalid characters.

Syntax for conditional logic using event objects and properties

Some objects and properties come from an event and are shared with Attentive via the event payload (see Custom Events for more information). You can use these event variables similarly to subscriber attribute variables, and they use similar syntax.

Sample event payload with event object and properties

Below is a sample payload from a custom event that sends data to Attentive when an order is shipped.

{
"type": "Custom Shipped Event",
"properties": {
"orderStatusURL": "example.com/orderstatus/54321",
"delivery_date": "May 10",
"CustNo": 63459333,
"OrderNo": "W0041160",
"PayMethod": "Visa",
"Total": 100.00,
"Loyalty_member": true,
"Loyalty_points": 250,
"products": [
{
"name": "Shirt",
"price": 4.50,
"imageURL": "https://google.com",
"productLink": "https://google.com"
},
{
"name": "Pants",
"price": 10.50,
"imageURL": "https://google.com",
"productLink": "https://google.com"
},
{
"name": "Hat",
"price": 2.50,
"imageURL": "https://google.com",
"productLink": "https://google.com"
}
],
"shipment": {
"carrier": "fedex",
"trackingNumber": 12345
}
},
"externalEventId": "37fb97a9-6cfd-4983-bd65-68d104d53b70",
"user": {
"phone": "+15555555555",
"email": "test@attentivemobile.com"
}
}

To use the attribute PayMethod as a variable in a message to a subscriber from the event above, use the following Liquid code: {{triggerEvent.custom['PayMethod']}}. You can add default values , too, as in this example: {{triggerEvent.custom['PayMethod'] | default: 'none'}}.

Sample Liquid code using conditional logic for event objects and properties

Below are a few examples that demonstrate how you can use operators in conjunction with the sample event payload and Liquid variable above.

Liquid code Output

Boolean

{% if triggerEvent.custom[‘Loyalty_member’] == true %}

Thanks for being a loyal customer! Use FREEGIFT at checkout for a special thank you from us.

{% else %}

Thank you for your purchase! Use FREESHIPPING at checkout to get shipping for your next order on the house!

{% endif %}

If the subscriber is a loyalty member:

Thanks for being a loyal customer! Use FREEGIFT at checkout for a special thank you from us.

If the subscriber isn’t a loyalty member:

Thank you for your purchase! Use FREESHIPPING at checkout to get shipping for your next order on the house!

String

{% if triggerEvent.custom[‘PayMethod’] == "Visa" %}

Thanks for being a loyal Visa customer! Use FREEGIFT at checkout for a special thank you from us.

{% else %}

Thank you for your purchase! Use FREESHIPPING at checkout to get shipping for your next order on the house!

{% endif %}

If the subscriber used a Visa to purchase:

Thanks for being a loyal Visa customer! Use FREEGIFT at checkout for a special thank you from us.

If the subscriber didn’t use a Visa to purchase:

Thank you for your purchase! Use FREESHIPPING at checkout to get shipping for your next order on the house!

Number

{% if triggerEvent.custom[‘Loyalty_points’] > 200 %}

Thanks for being a loyal customer! Use FREEGIFT at checkout for a special thank you from us.

{% else %}

Thank you for your purchase! Use FREESHIPPING at checkout to get shipping for your next order on the house!

{% endif %}

If the subscriber has over 200 loyalty points:

Thanks for being a loyal customer! Use FREEGIFT at checkout for a special thank you from us.

If the subscriber has 200 or fewer loyalty points:

Thank you for your purchase! Use FREESHIPPING at checkout to get shipping for your next order on the house!

Assign and capture variables

Liquid provides two useful tags for creating and manipulating variables: assign and capture. These tags are useful when creating reusable content or complex personalized messages in your email messages.

Assign

Use assign to create a new named variable.

Example: {% assign header = "WELCOME TO OUR SALE" %}

Note: Variable assignment isn’t supported in the drag-and-drop editor. However, you can use variable assignment in the HTML editor.

Capture

Use capture to create complex strings using other variables or Liquid expressions.

Example:

{% assign sale_date = "2023-09-01" %}
{% capture sale_message %}
Don't miss our big sale starting on {{sale_date}}!
{% endcapture %}

Use iterative logic with Liquid

Another way to use Liquid syntax to fine-tune personalization in your messages is to use the for tag to iterate. Iterative statements (or tags) using for allow you to loop through a list or array. For example, you can use iterative statements to display a list of products a subscriber added to their cart in a message.

Notes:
  • The Dynamic list content block only appears in the drag-and-drop editor if your event contains the corresponding list or product object.
  • You can use for tags in the HTML editor or with the dynamic list content block in the drag-and-drop email editor. This ensures that the resulting HTML in the email message is properly formatted. You can’t use them in the HTML block in the email drag-and-drop editor.

Below are a few examples using the same sample custom event payload from the previous section.

Sample event payload with a list of products from an event

{
"type": "Custom Shipped Event",
"properties": {
"orderStatusURL": "example.com/orderstatus/54321",
"delivery_date": "May 10",
"CustNo": 63459333,
"OrderNo": "W0041160",
"PayMethod": "Visa",
"Total": 100.00,
"Loyalty_member": true,
"Loyalty_points": 250,
"products": [
{
"name": "Shirt",
"price": 4.50,
"imageURL": "https://google.com",
"productLink": "https://google.com"
},
{
"name": "Pants",
"price": 10.50,
"imageURL": "https://google.com",
"productLink": "https://google.com"
},
{
"name": "Hat",
"price": 2.50,
"imageURL": "https://google.com",
"productLink": "https://google.com"
}
],
"shipment": {
"carrier": "fedex",
"trackingNumber": 12345
}
},
"externalEventId": "37fb97a9-6cfd-4983-bd65-68d104d53b70",
"user": {
"phone": "+15555555555",
"email": "test@attentivemobile.com"
}
}

Sample Liquid code using for tag to display list of products

Given the sample payload above, here’s how you can use the for tag to display a list of all products from this event, along with the price of each product:

{% for item in triggerEvent[‘custom’][‘products’] %}

Product Name: {{item['name']}}
Product Price: {{item['price']}}

{% endfor %}

This code retrieves all prices and model numbers for every product in an event payload for a given subscriber. However, if you’re writing this in Attentive’s HTML email editor, it also needs HTML tags so that it can be rendered properly in the actual email that’s sent to subscribers.

Here’s an example written with HTML:

<table align="center" role="presentation" style="mso-table-lspace:0;mso-table-rspace:0;color:#000;background-color:#fff;width:600px;margin:0 auto" width="600">
<tr>
<td style="mso-table-lspace:0;mso-table-rspace:0;text-align:left;font-weight:400;padding-bottom:5px;padding-top:5px;vertical-align:top;border-top:0;border-right:0;border-bottom:0;border-left:0">
{% for item in triggerEvent[‘custom’][‘products’] %}
<table class="image_block block-1" width="100%" border="0" cellpadding="10" cellspacing="" role="presentation" style="mso-table-lspace:0;mso-table-rspace:0;word-break:break-word">
<tr>
<td class="pad" style="width:100%">
<div class="alignment" align="center" style="line-height:10px">
<a href="{{product.link}}" target="_blank" style="outline:none" tabindex="-1">
<img src="{{product.image}}" style="height:auto;display:block;border:0;max-width:695px;width:100%" width="695">
</a>
</div>
</td>
</tr>
<tr>
<td>
<div style="color:#000;direction:ltr;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;letter-spacing:0;line-height:120%;text-align:left;mso-line-height-alt:16.8px">
<p style="margin:0">Product Name: {{item['name']}}</p>
</div>
</td>
</tr>
<tr>
<td>
<div style="color:#000;direction:ltr;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;letter-spacing:0;line-height:120%;text-align:left;mso-line-height-alt:16.8px">
<p style="margin:0">Product Price: {{item['price']}}</p>
</div>
</td>
</tr>
<tr>
<td>
<div class="alignment" align="left">
<a href="{{product.link}}" target="_blank" style="text-decoration:none;display:block;color:#fff;background-color:#000;border-radius:4px;width:50%;border-top:0px solid transparent;font-weight:400;border-right:0px solid transparent;border-bottom:0px solid transparent;border-left:0px solid transparent;padding-top:4px;padding-bottom:4px;font-family:Helvetica Neue, Helvetica, Arial, sans-serif;font-size:16px;text-align:center;mso-border-alt:none;word-break:keep-all;">
<span style="padding-left:4px;padding-right:4px;font-size:16px;display:inline-block;letter-spacing:normal;">
<span style="word-break: break-word; line-height: 32px;">Buy now</span>
</span>
</a>
</div>
</td>
</tr>
</table>
{% endfor %}
</td>
</tr>
</table>

And below is the output of the HTML above without any additional HTML tags or formatting:

HTML output of code sample above.

Troubleshooting

There are two common types of errors when using conditional and iterative logic with Liquid: data type errors and syntax errors.

Data type errors

Data values must be comparable in order for Liquid to properly evaluate and execute operators (e.g., , <,==). For example, your Liquid code won’t work as intended if you compare a string data value to a number data value.

If you use the custom events or the custom attributes API, you should also verify that values are properly formatted as follows:

  • Don’t wrap numbers in quotes. In the JSON payload, a properly formatted number looks similar to the following: "Total": 100.00
  • Don’t wrap booleans (true and false) in quotes. Properly formatted booleans look similar to the following in the JSON payload: "loyalty_member": true
  • Always wrap string values in quotes.

If you use Attentive custom attributes, check the Custom attributes page to see what attributes and data types exist. Contact your Attentive CSM or White Glove (whiteglove@attentive.com) to change data types if needed.

If you change a custom attribute’s data type (e.g., from a string to a number), make sure that all values match the new type. If any values don’t match, Liquid code that references the attribute may fail, causing your marketing emails to be dropped. Your transactional emails will still be sent, but they may contain missing or unresolved values.

Syntax errors

Like any code, Liquid must be written correctly to be executed properly. This is especially important if you’re using the HTML editor rather than the drag-and-drop editor. Always make sure you have closing tags {% %} and curly braces. We recommend using a code editor like Visual Studio Code with the Liquid code extension to help you make sure you aren’t missing key characters.

Articles in this section

Was this article helpful?
0 out of 0 found this helpful