Supported logic tags

Tip: What's the difference between %} and -%}? Here's how to handle Liquid generated whitespace.

IF

Simple if decision block.

  {% if item.Color == 'red' -%}
    <p>Red is the color</p>
  {% endif -%}

IF else

Just like a regular IF condition, the only difference is this adds another possible choice.

{% if item.Color == 'red' -%}
<p>Red is the color</p>
{% elseif item.Color == 'blue' -%}
  <p>Blue is the color</p>
{% else -%}
  <p>Neither red nor blue.</p>
{% endif -%}

UNLESS

Unless the condition is true the code is executed

{% unless item.Color == 'red' -%}
 <p>The color is not red.</p>
{% endunless -%}

or

{% unless item.Color == 'red' or item.Color == 'blue'-%}
	<p>The color is not red nor blue.</p>
{% endunless -%}

CASE

Do something based on the possible values of a variable. If none of the "known" values are encountered the last "else" branch will be executed.

{% case item.country -%}
  {% when 'DE' -%}
    Willkommen
  {% when 'ES' -%}
    Bienvenido
  {% when 'EN' -%}
    Welcome
  {% else -%}
    Bine ai venit
{% endcase -%}

FOR

FOR is used to loop over a collection of items.

{% for item in webapp1.items -%}
<p>
    This item's name is: {{item.name}} 
</p>
{% endfor -%}

In FOR loops you can also access the key/value pairs, for example:

<ul>
{% for getParam in this.globals.visitor -%} 
  <li>{{getParam[0]}} = '{{getParam[1]}}'</li>
{% endfor -%}
</ul>

will render the this.globals.visitor object like so:

<ul>
  <li>deviceClass = 'desktop'</li>
  <li>ip = '10.10.10.10'</li>
  <li>country = 'US'</li>
  <li>userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36'</li>
</ul>

Break

Causes the for loop to stop iterating when it encounters the break tag.

{% for i in (1..5) -%}
{% if i == 4 -%}
{% break %} {% else -%}
{{ i }} {% endif -%}
{% endfor -%}

Will output: 1 2 3

Continue

Causes the for loop to skip the current iteration when it encounters the continue tag.

{% for i in (1..5) -%}
{% if i == 4 -%}
{% continue %} {% else -%}
{{ i }} {% endif -%}
{% endfor -%}

Will output: 1 2 3 5

Limit and Offset

Liquid for loops support the ability to limit and offset the results. You can limit the number of results by a value and offset the results by a value also.
More can be read about these loop filters in the filters reference.

In a loop you can access these variables:

  • {{forloop.length}} - length of the entire for loop (integer)
  • {{forloop.index}} - index of the current iteration (integer)
  • {{forloop.index0}} - index of the current iteration (zero based) (integer)
  • {{forloop.rindex}} - how many items are still left? (integer)
  • {{forloop.rindex0}} # => how many items are still left? (zero based) (integer)
  • {{forloop.first}} - is this the first iteration? (boolean)
  • {{forloop.last}} - is this the last iteration? (boolean)

The quickest way to see these variables in action is to iterate over the globals object. Paste this code in any page:

<ul>
{% for item in globals -%}
    <li>{{item[0]}}: {{item[1]}}<br/>
        <p>
            forloop.length is {{forloop.length}} - length of the entire for loop<br/>
            forloop.index is {{forloop.index}}  - index of the current iteration<br/>
            forloop.index0 is {{forloop.index0}} - index of the current iteration (zero based)<br/>
            forloop.rindex is {{forloop.rindex}} - how many items are still left?<br/>
            forloop.rindex0 is  {{forloop.rindex0}} - how many items are still left? (zero based)<br/>
            forloop.first is {{forloop.first}}  - is this the first iteration?<br/>
            forloop.last is {{forloop.last}}   - is this the last iteration? <br/>
        </p>
    </li>
{% endfor -%}
</ul>

You can only iterate over a part of a collection, for example if you have a large list of customers you can only iterate over 20 at a time using the limit and offset variables.

 {module_data resource="customers" version="v3" template="" collection="customerInfo" order="firstName" fields="email1, firstName, lastName, id"}
//this module creates a collection named customerInfo that first 10 customers on your site ordered by the firstName and includes the fields specified in the fields parameter
//let's display the data in the collection in a table:
<table>
    <thead>
        <th>No.</th>
        <th>Name</th>
        <th>Email</th>
    </thead>
    {%for item in customerInfo.items limit:4 offset:0-%}
//looping the first 4 items of the collection
    <tr>
        <td>{{forloop.index}}</td>
//in the first td we output the row number using forloop.index
        <td>{{item.firstName}} {{item.lastName}}</td>
        <td>{% if {{item.email1.value}}-%}
            {{item.email1.value}}
            {%else-%}
            N/A
            {%endif-%}
//in this if block we check that the current user has the email1 address filled in. Otherwise "N/A" will be displayed.
        </td>
    </tr>
{%endfor-%}
</table>

The loop can also iterate in reverse using the reversed parameter.

For example, let's use the same customer collection from the previous example this time orders by firstName desc:

 {module_data resource="customers" version="v3" template="" collection="customerInfo" order="-firstName" fields="email1, firstName, lastName, id"}
//this module creates a collection named customerInfo that first 10 customers on your site ordered by the firstName and includes the fields specified in the fields parameter
{%for item in customerInfo.items reversed -%}
<li>{{item.firstName}}</li>
{%endfor-%}
//this loop will go over the items in the collection in reverse order

CYCLE

Render one of a few possible items. For example:

{% cycle 'red', 'green', 'blue' -%}
{% cycle 'red', 'green', 'blue' -%}
{% cycle 'red', 'green', 'blue' -%}
{% cycle 'red', 'green', 'blue' -%}

renders:

red
green
blue
red

INCLUDE

Include is used to pull data from another page.

You can think of it much like you would think of a content holder. The main difference is when you get a page's contents using include the Liquid objects and collections will become available in your main page.

For example, paste this code in a page, name it to-be-included.html:

<html>
<head><head>
<body>
{module_data resource="customers" subresource="orders" resourceId="{{globals.user.entityid}}" version="v3" template="" collection="customerOrders"} 
//this gets the list of orders for the logged in customer
</body>
</html>

On another page (the main page) paste this code:

{%include "/to-be-included.html"-%}
<pre>{{customerOrders | json}}</pre>
//even though the collection customerOrders is not defined in the main page you will still see its contents

This feature is particularly useful in helping you keep the Liquid content organized, for example you can group pages that contains snippets of Liquid code (orders for the logged in customers, more complex code snippets that loop other objects or take into account more factors - is the user a wholesaler, does he have access to a particular page, does he have an order over $50 in the last week and so on) in a single folder and include them when needed.

ASSIGN

This is used to create a new variable.

{% assign new_variable = "my new value" -%}

Or update a variable's value:

{% assign new_variable = "the new value" -%}

CAPTURE

Assign a block of text, HTML code to a variable.

{% capture item_date -%}<span style="color:blue">{{item.releaseDate}}</span>{% endcapture -%}

You can then use {{item_date}} to output the release date of the item in blue. The HTML code or text between the capture tags does not render on the page.

COMMENT

Comments out a block of text. The text between the comment tags does not render in the front-end.

{%comment-%}
	Do not forget to remove comments
{%endcomment-%}

The comment will only be visible in the Admin Console.

RAW

Raw renders liquid markup in plain text.

{%raw-%}
	{{this | json}}
{%endraw-%}

This will render the Liquid code in plain text.

TABLEROW

This will draw a table. You can specify how many columns the table will contain using the "cols:" value.


<table>
{% tablerow item in webapp1.items cols:2 -%}
    {{item.name}}{{item.counter}}
{% endtablerow -%}
</table>

Examples

A more complex example that uses a FOR loop to go over the items of a webapp collection and make some additional decisions using the CASE statement:

{% assign european_make = "This vehicle is from Europe!"-%} //create a variable named european_make
{% for item in webapp1.items -%} // looping the webapp1.items {% if item.Color == "red" and (item.Country contains "U" or item.Country == "US") and item.name contains "a" and item.name contains "e"-%} <p> Item number {{item.counter}} name is: {{item.name}} and its color is <span style="color:{{item.Color}}">{{item.Color}}</span> and country is {{item.Country}} </p> {%unless item.country == "US" or item.country == "AU"-%} // if the country is not US nor AU display the contents of the european_make variable {{european_make}} <br/> {%endunless-%} {%comment-%} this is a comment - if you also have Japanese cars the "unless" statement above is not accurate - whoops... {%endcomment-%} {% capture item_productionDate -%}<span style="color:blue">{{item.releaseDate}}</span>{% endcapture -%} {% case item.country -%} {% when 'DE' -%} Jahr der Wagen rollte vom Band auf {% when 'EN' -%} Año el coche salió de la línea de montaje el {% else -%} Year the car rolled off the assembly line on {% endcase -%} {{item_productionDate}} <br/> <br/> {% endif -%} {% endfor -%}