Liquid - Tags: Loops
for
Liquid allows for
loops over collections to iterate over arrays, hashes, and ranges of integers.
Iterating over an array
{% for item in array %}
{{ item }}
{% endfor %}
Iterating over a hash
When iterating a hash, item[0]
contains the key, and item[1]
contains the value:
{% for item in hash %}
{{ item[0] }}: {{ item[1] }}
{% endfor %}
Instead of looping over an existing collection, you can also loop through a range of numbers.
Ranges look like (1..10)
— parentheses containing a start value, two periods, and an end value.
The start and end values must be integers or expressions that resolve to integers.
Input if item.quantity is 4
{% for i in (1..item.quantity) %}
{{ i }}
{% endfor %}
Output
1,2,3,4
Breaking and continuing
You can exit a loop early with the following tags:
{% continue %}
: immediately end the current iteration, and continue thefor
loop with the next value.{% break %}
: immediately end the current iteration, then completely end thefor
loop.
Both of these are only useful when combined with something like anif
statement.
{% for page in pages %}
{% comment %}
Skip anything in the hidden_pages array,
but keep looping over the rest of the values
{% endcomment %}
{% if hidden_pages contains page.url %}
{% continue %}
{% endif %}
{% comment %} If it's not hidden, print it. {% endcomment %}
* [page.title](page.url)
{% endfor %}
{% for page in pages %}
* [page.title](page.url)
{% comment %}
After we reach the "cutoff" page,
stop the list and get on with whatever's after the "for" loop:
{% endcomment %}
{% if cutoff_page == page.url %}
{% break %}
{% endif %}
{% endfor %}
Helper variables
During every for
loop, the following helper variables are available for extra styling needs:
Variable | Description |
---|---|
forloop.length | length of the entire for loop |
forloop.index | index of the current iteration |
forloop.index0 | index of the current iteration (zero-based) |
forloop.rindex | how many items are still left? |
forloop.rindex0 | how many items are still left? (zero-based) |
forloop.first | is this the first iteration? |
forloop.last | is this the last iteration? |
forloop.parentloop | Provides access to the parent loop, if present. |
Find examples at the Liquid Objects page.
Optional arguments
There are several optional arguments to the for
tag that can influence which items you receive in your loop and what order they appear in:
limit:<INTEGER>
lets you restrict how many items you get.offset:<INTEGER>
lets you start the collection with the nth item.reversed
iterates over the collection from last to first.
Restricting elements
array = [1,2,3,4,5,6]
{% for item in array limit:2 offset:2 %}
{{ item }}
{% endfor %}
Output
3,4
Reversing the loop:
{% for item in collection reversed %}
{{ item }}
{% endfor %}
Handling an empty collection
A for
loop can take an optional else
clause to display a block of text when there are no items in the collection:
items => []
{% for item in items %}
{{ item.title }}
{% else %}
There are no items!
{% endfor %}
cycle
Loops through a group of strings and outputs them in the order that they were passed as parameters. Each time cycle
is called, the next string that was passed as a parameter is output.
{% for i in (1..4) -%}
{% cycle 'one', 'two', 'three' %}
{% endfor -%}
will result in
one
two
three
one
Though cycle
is often used within a for
loop block, it also works on its own by placing multiple copies of the tag on the page. Liquid treats each tag as part of the same group, even if their contents are different.
{% cycle 'one', 'two', 'three' %}
{% cycle 'banana', 'apple', 'orange' %}
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
will result in
one
apple
three
one
If you want to have total control over cycle
groups, you can optionally specify the name of the group. This can even be a variable.
{% cycle 'group 1': 'one', 'two', 'three', 'four' %}
{% cycle 'group 1': 'one', 'two', 'three', 'four' %}
{% cycle 'group 2': 'one', 'two', 'three', 'four' %}
{% cycle 'group 2': 'one', 'two', 'three', 'four' %}
{% cycle 'group 1': 'one', 'two', 'three', 'four' %}
{% cycle 'group 1': 'one', 'two', 'three', 'four' %}
will result in
one
two
one
two
three
four
Liquid assumes that each cycle
tag without a name is part of the same nameless group. For example:
{% cycle 'A', 'B', 'C', 'D' %}
{% cycle 'group 3': 'one', 'two', 'three', 'four' %}
{% cycle 'group 4': 'one', 'two', 'three', 'four' %}
{% cycle 'group 4': 'one', 'two', 'three', 'four' %}
{% cycle 'group 3': 'one', 'two', 'three', 'four' %}
{% cycle 'group 3': 'one', 'two', 'three', 'four' %}
{% cycle 'A', 'B', 'C', 'D' %}
will result in
A
one
one
two
two
three
B
ifchanged
The ifchanged
tag is typically called inside a {% for %} loop because it executes a block of code but only outputs the result if this is the first time it was called or if the previous call had a different result.
Input
{% assign list = "1,1,1,1,3,3,3,2,1,3,1,2" | split: "," %}
{% for item in list -%}
{%- ifchanged %} {{ item }} {% endifchanged -%}
{%- endfor %}
Output
1 3 2 1 3 1 2
tablerow
Generates rows for an HTML table. Must be wrapped in opening <table>
and closing </table>
HTML tags. The tablerowloop object describes the full list of attributes available within a tablerow
.
Input
<table>
{% tablerow product in collection.products %}
{{ product.title }}
{% endtablerow %}
</table>
Output
<table>
<tr class="row1">
<td class="col1">Cool Shirt</td>
<td class="col2">Alien Poster</td>
<td class="col3">Batman Poster</td>
<td class="col4">Bullseye Shirt</td>
<td class="col5">Another Classic Vinyl</td>
<td class="col6">Awesome Jeans</td>
</tr>
</table>
tablerow tag parameters
cols
Defines how many columns the tables should have.
Input
<table>
{% tablerow product in collection.products cols:2 %}
{{ product.title }}
{% endtablerow %}
</table>
Output
<table>
<tr class="row1">
<td class="col1">Cool Shirt</td>
<td class="col2">Alien Poster</td>
</tr>
<tr class="row2">
<td class="col1">Batman Poster</td>
<td class="col2">Bullseye Shirt</td>
</tr>
<tr class="row3">
<td class="col1">Another Classic Vinyl</td>
<td class="col2">Awesome Jeans</td>
</tr>
</table>
limit
Exits the tablerow
loop after a specific index.
{% tablerow product in collection.products cols:2 limit:3 %}
{{ product.title }}
{% endtablerow %}
offset
Starts the tablerow
loop at a specific index.
{% tablerow product in collection.products cols:2 offset:3 %}
{{ product.title }}
{% endtablerow %}
range
Defines a range of numbers to loop through. The range can be defined by both literal and variable numbers.
<table>
{% tablerow i in (3..5) %}
{{ i }}
{% endtablerow %}
</table>
{% assign num = 4 %}
<table>
{% tablerow i in (1..num) %}
{{ i }}
{% endtablerow %}
</table>
Note
This topic is a compilation of knowledge found at: Shopify Themes, Liquid Documentation, Liquid Gem Documentation, and Liquid for Designers.