Using tags to put logic into your campaigns, templates and landing pages

Overview

Tags are used when building logic to tell your content what to do, for example:

<!--{% if contact.data.firstname == 'ben' %}-->
Hey Ben!
<!--{% else %}-->
Hello there!
<!--{% endif %}-->

The above example will show different content, depending on whether or not the contact's first name is Ben. This works in a similar way to dynamic content.

A more interesting example is using for-loops, for example:

{% for book in contact.addressbooks %}
{{ book.name }} <br/>
{% endfor %}

This will get the list of address books that a contact is in, and for each address book show the name of the book followed by a line break.

Supported tags

Important

If your Liquid tags contain HTML reserved characters, wrap all those tags and any nested tags, including any {% elseif %}, {% else %}{% case %}, and {% when %} tags, in HTML comments. Otherwise, those characters are converted to HTML character entities, which may break your HTML. For example:

<!--{% if contact.data.age > 18 %}-->
Access granted
<!--{% else %}-->
Access denied
<!--{% endif %}-->

Don't wrap data objects such as {{ contact.data.firstname }} in HTML tags, otherwise this content will not be rendered.

Important

Don't use the following variable names. These names won't work because they're reserved for system-defined values:

  • account
  • contact
  • token
  • campaign

Assign

The {% assign %} tag stores data in a variable for output (or logic) elsewhere in the campaign, template, or landing page.

Enter the name of your chosen variable after the {% assign %} tag. For example:

<!--{% assign fullname = contact.data.firstname | append: ' ' | append: contact.data.lastname %}-->
{{ fullname }}

Output: Beatrix Potter

Capture

The {% capture %} tag stores all content that is between a {% capture %} tag and an {% endcapture %} tag in a variable. Use this tag for longer variables than those stored in an {% assign %} tag.  For example:

<!--{% capture fullname %}-->{{contact.data.firstname}} {{contact.data.lastname}}<!--{% endcapture %}-->
{{ fullname }}

Output: Beatrix Potter

Comment

The contents of a {% comment %}{% endcomment %} block is not rendered. Use this block to make a note in your markup. A comment block begins with a {% comment %} tag and ends with an {% endcomment %} tag. For example:

{% comment %}
This bit of markup does something clever to assign the right gender to the contact
{% endcomment %}

Output: nothing

Raw

The contents of a {% raw %}{% endraw %} block is not evaluated as liquid markup when your campaign, template, or landing page is rendered. You can use this tag to include raw liquid markup. For example:

My {% raw %}{{ contact.data.fullname }}{% endraw %} is {{ contact.data.fullname }}.

Output: My {{ contact.data.fullname }} is Michael Caine.

If (else and elseif)

{% if %}{% endif %} blocks provide basic conditional logic as to what content should be shown or not shown. An {% if %} tag contains a condition, and if that condition is met then the content in the {% if %}{% endif %} block is included in the campaign, template, or landing page. For example:

Hi there! <!--{% if contact.data.firstname == 'Barney' %}-->You're looking particularly awesome. <!--{% endif %}-->Isn't it a lovely day? Would you like a piece of cake?

Output (for Barney): Hi there! You're looking particularly awesome. Isn't it a lovely day? Would you like a piece of cake?
Output (for anyone else): Hi there! Would you like a piece of cake?

Elseif tags can be used inside an if block to add further conditional content if the first condition is not met. For example:

Hi there! <!--{% if contact.data.firstname == 'Barney' %}-->You're looking particularly awesome. <!--{% elseif contact.data.gender == 'Male' %}-->Isn't it a lovely day? <!--{% endif %}-->Would you like a piece of cake?

Output (for Barney): Hi there! You're looking particularly awesome. Would you like a piece of cake?
Output (for all other males): Hi there! Isn't it a lovely day? Would you like a piece of cake?
Output (for anyone else): Hi there! Would you like a piece of cake?

Else statements can be used inside an if block to add default conditions if the none of the preceding conditions are met. For example:

Hi there! <!--{% if contact.data.firstname == 'Barney' %}-->You're looking particularly awesome. <!--{% elseif contact.data.gender == 'Male' %}-->Isn't it a lovely day? <!--{% else %}-->Would you like a piece of cake?<!--{% endif %}-->

Output (for Barney): Hi there! You're looking particularly awesome.
Output (for all other males): Hi there! Isn't it a lovely day?
Output (for anyone else): Hi there! Would you like a piece of cake?

In these examples, == is an operator that is used to test equivalence.

Unless

The unless block is the reverse of the if block, it shows its content if the condition evaluates to false. It begins with a {% unless %} tag and ends with an {% endunless %} tag. For example:

Yo, {{ contact.data.firstname }}!<!--{% unless contact.data.firstname == 'Ted' %}--> Haaaaave you met Ted?<!--{% endunless %}-->

Output (for Ted): Yo, Ted!
Output (for anyone else): Yo, Tracy! Haaaaave you met Ted?

Case

A case block is used in place of a series of if statements, where different content is to be shown based on the value of a single field. A case block starts with a case tag, ends with a endcase tag, uses when tags for each condition, and a else tag to denote the default content. For example:

<!--{% case contact.data.firstname %}-->
<!--{% when 'Simon' %}-->
A lager, sir?
<!--{% when 'Tink' %}-->
Lager top for the gentleman?
<!--{% when 'Simone' %}-->
Can I get you a glass of red?
<!--{% else %}-->
I ain't getting you a drink!
<!--{% endcase %}-->

Output (for Simon): A lager, sir?
Output (for Tink): Lager top for the gentleman?
Output (for Simone): Can I get you a glass of red?
Output (for anyone else): I ain't getting you a drink! 

Iteration logic

For

A {% for %}{% endfor %} block  iterates through the contents of an array. For example:

{% for book in contact.addressbooks %}
{{ book.name }}<br/>
{% endfor %}

Output: A list of all address books that a contact is in, with each list item separated by a line break.

for loop stores each item of an array in a variable, in this case the book variable. Rather than referring to contact.addressbooks[n].name, we now refer to book.name.

Tip

By using a sort filter, we can specify the order that the iterations occur in. For example:

<!--{% assign mybooks = contact.addressbooks | sort: 'name' %}-->
{% for book in mybooks %}
{{ book.name }}<br>
{% endfor %}

Output: An alphabetical list of all the address books that a contact is in, with each list item separated by a line break.

Reverse order

You can reverse the direction that a {% for %}{% endfor %} block iterates through an array by using the reversed parameter. For example:

<!--{% assign mybooks = contact.addressbooks | sort: 'name' %}-->
{% for book in mybooks reversed %}
{{ book.name }}<br>
{% endfor %}

Output: A list of all the address books that a contact is in, in reverse alphabetical order.

Limited iterations

You can limit the number of times a for loop will iterate by using the limit parameter. For example:

<!--{% assign mybooks = contact.addressbooks | sort: 'name' %}-->
{% for book in mybooks limit: 3 %}
{{ book.name }}<br>
{% endfor %}

Output: An alphabetical list of the first three address books that a contact is in.

Offset iterations

You can decide to not start at the first item in an array. Use the offset parameter to skip a number of items in an array. For example:

<!--{% assign mybooks = contact.addressbooks | sort: 'name' %}-->
{% for book in mybooks limit: 3 offset: 2 %}
{{ book.name }}<br>
{% endfor %}

Output: An alphabetical list of the third, fourth and fifth address books that the contact is in.

Ranged iterations

If you want to iterate for a set number of times through a piece of text/markup, but it is not tied to a particular array you can do this using a range. For example to iterate through a piece of code five times you can use this:

<!--{% assign stars = 5 %}-->
<!--{% for i in (1..stars) %}-->
&#8902;
<!--{% endfor %}-->

Output: Five stars (&#8902; is code for a star)

Your ranged iteration does not need to start at "1" for example:

{% for value in (68..72) %}
{{ value }}
{% endfor %}

Output: 68 69 70 72

Break

The break tag causes a loop to stop iterating, even if it has not reached the final iteration. For example, this loop skips numbers that are divisible by 7:

<!--{% for i in (1..10) %}-->
<!--{% assign remainder = i | modulo:7 %}-->
<!--{% if remainder == 0 %}--> <!--{% break %}--> <!--{% endif %}-->
{{ i }}
<!--{% endfor %}-->

Output: 1 2 3 4 5 6.

Continue

The continue tag causes a loop to jump to the next iteration without  completing the current one. For example, this loop skips the numbers that are divisible by 3:

<!--{% for i in (1..10) %}-->
<!--{% assign remainder = i | modulo:3 %}-->
<!--{% if remainder == 0 %}--> <!--{% continue %}--> <!--{% endif %}-->
{{ i }}
<!--{% endfor %}-->

Output: 1 2 4 5 7 8 10

Cycle

The cycle tag is used within loops. The parameter for a cycle tag is a list of options; each time a loop iterates, it will take the next option in the list, returning to the first. For example:

{% for i in (1..20) %}
<p style="color:{% cycle '#FF0000', '#00FF00', '#0000FF' %};">
{{ i }}
</p>
{% endfor %}

Output: 1 2 3  4   5   6 7   8   10  11   12 13   14   15 16   17   18  19   20

Forloop

A forloop is not a tag, but an object that you can reference from a for block. Use a forloop object to find out where in the series of iterations we currently are. For example:

<!--{% for i in (1..10) %}-->
<!--{% if forloop.last %}--> and <!--{% endif %}-->{{ i }}<!--{% unless forloop.last %}-->, <!--{% endunless %}-->
<!--{% endfor %}-->

Output: 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10

The following elements of the forloop object can be referenced:

forloop.first
Returns 'true' if this is the first iteration through the loop; otherwise it returns 'false'.
forloop.index
Returns the current index of the loop. i.e. the number of iterations that have been started, starting at 1 for the first iteration.
forloop.index0
Returns the current index of the loop starting at zero. i.e. the number of iterations that have ended.
forloop.last
Returns 'true' if this is the last iteration through the loop; otherwise it returns 'false'.
forloop.rindex
Returns the loop index starting in reverse order (so 1 for the last iteration, 2 for the penultimate iteration and so on).
forloop.rindex0
Returns the loop index starting in reverse order starting at zero (so 0 for the last iteration, 1 for the penultimate iteration and so on).
forloop.length
Returns the total number of iterations the loop will go through.

Operators for logical statements

When using logical tags such as if, else and unless the following operators can be used used:

  • == → Is equal to
  • != → Is not equal to
  • > → Is greater than
  • < → Is less than
  • >= → Is greater than or equal to
  • <= → Is less than or equal to
  • contains → Contains

Conditions can be chained together using or and and.

Examples

<!--{% if contact.data.firstname == 'ben' %}-->
Hey Ben
<!--{% endif %}-->

Conditions can also be combined:

<!--{% if contact.data.firstname == 'ben' and contact.data.age < 12 %}-->
Hey young Ben
<!--{% endif %}-->

And then using the contains operator you could do:

<!--{% if contact.data.firstname contains 'B' %}-->
You are truly awesome; your name contains a B
<!--{% endif %}-->

True and false values

If you use a non-boolean data type in a boolean context, for example, a conditional tag, then Liquid decides whether it is true or false. Data types that return as true or false are known as truthy and falsy, respectively.

In Liquid, all values are truthy except for nil and false.

Did you find this article helpful?

Can we help?

Thanks for using Dotdigital. If you need more help or support, then contact our support team.