Skip to documentation content

Control Flow

Control Flow

Methods that branch, loop, and include template regions, plus the forloop object.

{{ forloop }} is available inside {% for %} and exposes index, first, last, and length. The loop method and that helper object are documented on this page.

{% if %}

Conditional branching to only execute and output a block of code if a certain condition is met. May specify multiple blocks with separate conditions using "elsif"/"elseif" and "else" clauses if desired.

{% if condition %}
Parameters
condition requiredcondition
Single or compound condition using 'and'/'or'
{% elsif condition %}
Parameters
condition requiredcondition
Single or compound condition using 'and'/'or'

Secondary condition to evaluate. If none of the previous blocks were executed and the current condition is met, the following block of code will be executed and output to the template.

{% elseif condition %}
Parameters
condition requiredcondition
Single or compound condition using 'and'/'or'

Alternate name for the {% elsif %} method, with the same functionality.

{% else %}

Fallback block of code to execute and output if none of the previous blocks were executed.

{% endif %}

This method creates a new liquid context for storing and manipulating variables.

Alternatively, if you only want to execute a block of code if a certain condition is NOT met, use the "unless" tag instead.

Example Choose output with if and elseRun one block when a condition is true, and a fallback block when it is not.
Liquid
{%- var status = 'published' -%}
{%- if status == 'published' -%}
	<p>This content is live.</p>
{%- else -%}
	<p>This content is hidden.</p>
{%- endif -%}
Output
<p>This content is live.</p>
Example Choose among several conditions with elsifAdd extra branches with elsif. The first matching condition wins; else runs only when none match.
Liquid
{%- var role = 'editor' -%}
{%- if role == 'admin' -%}
	<p>You can manage the site.</p>
{%- elsif role == 'editor' -%}
	<p>You can update content.</p>
{%- else -%}
	<p>You have read-only access.</p>
{%- endif -%}
Output
<p>You can update content.</p>
Example Output a value only when it is validUse is_valid inside if to skip empty or missing values and show a fallback.

When the value is present

Liquid
{%- var heading = 'Welcome' -%}
{%- if heading is_valid -%}
	<h2>{{ heading | escape }}</h2>
{%- else -%}
	<h2>Untitled</h2>
{%- endif -%}
Output
<h2>Welcome</h2>

When the value is empty

Liquid
{%- var heading = '' -%}
{%- if heading is_valid -%}
	<h2>{{ heading | escape }}</h2>
{%- else -%}
	<h2>Untitled</h2>
{%- endif -%}
Output
<h2>Untitled</h2>

{% unless %}

Inverse conditional. Only executes and outputs a block of code if a certain condition is NOT met. May specify additional "elsif"/"elseif" and "else" clauses if desired, which will be treated the same as for the {% if %} method.

{% unless condition %}
Parameters
condition requiredcondition
Single or compound condition using 'and'/'or'
{% elsif condition %}
Parameters
condition requiredcondition
Single or compound condition using 'and'/'or'

Secondary condition to evaluate. If none of the previous blocks were executed and the current condition is met, the following block of code will be executed and output to the template.

{% elseif condition %}
Parameters
condition requiredcondition
Single or compound condition using 'and'/'or'

Alternate name for the {% elsif %} method, with the same functionality.

{% else %}

Fallback block of code to execute and output if none of the previous blocks were executed.

{% endunless %}

This method creates a new liquid context for storing and manipulating variables.

Example Include sidebar template unless a query param is falseInclude a sidebar template only when a query parameter is not false, using unless.
Liquid
{%- unless request.query_params contains "show_sidebar=false" -%}
	{%- if request.query_params has_key "show_sidebar" -%}
		{%- include "_custom_sidebar" type:request.query_params.show_sidebar -%}
	{%- else -%}
		{%- include "_default_sidebar" type:request.query_params.show_sidebar -%}
	{%- endif -%}
{%- endunless -%}

{% case %}

Switch-like control flow that compares a value against one or more "when" options and optionally an "else" fallback.

{% case variable %}
Parameters
variable requiredvariable
The name of the variable containing the value to compare against "when" options
{% when options %}
Parameters
options requiredlist
One or more values. May use the variable arguments syntax. Values to compare against the case variable to determine if this block should be executed or skipped

Defines the start of the block that will be executed and output to the template if the case variable matches one of the options. Must include at least one option, but may include multiple options separated either by commas or the word "or".

{% else %}

Defines the fallback code that will be executed and output to the template if none of the "when" blocks match the case varaible.

{% endcase %}

This method creates a new liquid context for storing and manipulating variables.

Example Case statement comparing custom field to stringUse case/when to compare a custom field value to multiple string options and branch accordingly.
Liquid
{%- case page.title_type.value -%}
	{%- when 'fullwidth' -%}
		<span class="fullwidth">This is full width title</span>
	{%- when 'halfwidth' or 'quarterwidth' -%}
		<span class="{{page.title_type.value}}">This is partial width title</span>
	{%- when "empty", "none", "null", "skip" -%}
		{%- comment %}No title{% endcomment -%}
	{%- else -%}
		This title does not have a span
{%- endcase -%}

{% for %}

Iterates through every item in a list. Executes and outputs a block of code to the template for each item in the list.

{% for item in collection reversed? [limit:num]? [offset:value]? %}
Parameters
item requiredvariable
The name for the variable to assign each item in the collection to
collection requiredlist
One or more values. May use the variable arguments syntax. The list of items to iterate
reversed optionalbool
If true, the items will be iterated in reverse order. Note that this takes effect after the offset and limit are applied
limit optionalinteger
offset optionalinteger
The number of items to skip at the beginning of the list. Alternatively, use the keyword "continue" to resume iteration of the list from the last time the same item and collection names were used in a for loop
{% else %}

If there are no items to iterate, the "else" block will be executed and output instead. This may be for several reasons, such as if the collection is not a list or is empty, or if the offset is greater than the size of the list.

{% continue %}

Skips to the next iteration of the current loop.

{% break %}

Exits the current loop immediately.

{% endfor %}

This method creates a new liquid context for storing and manipulating variables.

Use {% for item in list %} ... {% endfor %} to iterate over collections such as blog posts, menu items, or query results. The loop variable (for example, item) is set to each element in turn and is available only inside the loop. You can also iterate over a range of integers with range syntax (for example, (1..10)).

Before looping, chain filters to shape the list: where to filter, sort to order, and limit or slice to take the first N items or a segment. That keeps the loop simple and often clearer than putting a lot of logic inside the loop.

Inside {% for %}, the forloop object provides properties such as forloop.first, forloop.last, forloop.index, and forloop.length. Use these to control output—for example, commas between items but not after the last one, or first/last styling.

When the list might be empty, guard output: use the default filter for a fallback message, or wrap the loop in {% if list.size > 0 %} so you do not render an empty block. See the forloop object reference and the linked examples for more detail.

Example Loop over a collection and use forloop propertiesLoop over a collection and use forloop properties (first, last, index, length, etc.) for conditional output.
Liquid
{%- for item in collection -%}
	<div class="item-{{forloop.index0}}{% if forloop.first %} first{% elsif forloop.last %} last{% endif %} {% cycle forloop.name: "even", "odd" %}">
		<span class="itemcount">Item {{forloop.index}} out of {{forloop.length}}</span><br />
		<span class="itemvalue">{{ item }}</span><br />
		<span class="itemsleft">{{forloop.rindex0}} items remaining</span>
	</div>
{%- endfor -%}
Example How to use the for method

Basic: iterate through a collection

Liquid
{%- for item in collection -%}
	{{ item }}
{%- endfor -%}

This example will iterate through the collection and output each item.

Use the forloop variables to access loop properties

Liquid
{%- for item in collection -%}
	<span class="index-{{ forloop.index0 }}{% if forloop.first %} first{% elsif forloop.last %} last{% endif %}">Item {{ forloop.index }} out of {{ forloop.length }}</span>
{%- endfor -%}

You can use the automatically generated forloop variable to access loop properties like index, first, last, length, and more.

Watch out for nested forloop variables

Liquid
{%- for outer in collection1 -%}
	{%- for inner in collection2 -%}
		Outer Item #{{ forloop.index }}
	{%- endfor -%}
{%- endfor -%}

Note that you cannot access the outer forloop variable from within the inner forloop. This example will output the inner forloop index, not the outer forloop index.

Correcting access to nested forloop variables

Liquid
{%- for outer in collection1 -%}
	{%- var outerloop = forloop -%}{%- for inner in collection2 -%}
		Outer Item #{{ outerloop.index }}
	{%- endfor -%}
{%- endfor -%}

To access the outer forloop from within an inner loop you can store the outer forloop variable in a new variable with a different name and then access it using the new variable.

For loop with limit, and the continue keyword

Liquid
{%- var mycollection = (1..6) -%}
First Three: {% for item in mycollection limit:3 -%}
	<span class="index-{{forloop.index0}}{% if forloop.first %} first{% endif %}{% if forloop.last %} last{% endif %}">{{item}}</span>
{%- endfor %}
The Rest: {% for item in mycollection offset:continue -%}
	<span class="index-{{forloop.index0}}{% if forloop.first %} first{% endif %}{% if forloop.last %} last{% endif %}">{{item}}</span>
{%- endfor -%}
Output
First Three: <span class="index-0 first">1</span><span class="index-1">2</span><span class="index-2 last">3</span>
The Rest: <span class="index-0 first">4</span><span class="index-1">5</span><span class="index-2 last">6</span>

This example breaks a single collection into two separate loops using the limit and continue arguments. Note that the forloop variables (first, last, index, etc.) are reset for each loop.

For loop reversed

Liquid
{%- for number in (1..10) reversed -%}
	{%- if number == 9 -%}
		{%- continue -%}
	{%- elseif number == 6 -%}
		{%- break -%}
	{%- endif -%}
	<span class="index-{{forloop.index0}} {% if forloop.first %}first {% endif %}{% if forloop.last %}last {% endif %}{% cycle exampleclasses:'even', 'odd' %}">{{number}}</span>
{%- endfor -%}
Output
<span class="index-0 first even">10</span><span class="index-2 odd">8</span><span class="index-3 even">7</span>

This example reverses the list before looping through it. Note that the list is reversed BEFORE looping through it, so the indexes may appear to be in reverse order but they are not. Also note that the continue and break keywords work as expected and do not affect the forloop.first and forloop.last properties.

For loop with numeric offset

Liquid
{%- var items = (1..8) -%}
Skip first 2: {% for item in items offset:2 -%}
	{%- unless forloop.first %} {% endunless %}{{ item }}
{%- endfor -%}
Output
Skip first 2: 3 4 5 6 7 8

Use a numeric offset to skip the first N items in the collection. Here offset:2 skips 1 and 2, so the loop outputs 3 through 8.

Example Display linked titles from a list of itemsMap a collection of entities into a human-readable list of titles linking to the entities.
Liquid
{%- for entity in collection.items -%}
	{%- unless forloop.first or forloop.length == 2 %},{% unless forloop.last %} {% endunless %}{% endunless %}{% if forloop.last %}and{% endif %} {{ entity.linked_title -}}
{%- else -%}
	(none)
{%- endfor -%}
Example Loop over POST parametersIterate over request.post_params (e.g. form fields) to list or process each parameter.
Liquid
<h4>Post Parameters</h4>
<dl>
{%- for param in request.post_params -%}
	<dt>{{param}}</dt>
	<dd>
		{%- if request.post_params.by_name[param] is_list -%}
			<ul>
				{%- for value in request.post_params.by_name[param] -%}
					<li>{{ value }}</li>
				{%- endfor -%}
			</ul>
		{%- else -%}
			{{- request.post_params.by_name[param] -}}
		{%- endif -%}
	</dd>
{%- endfor -%}
</dl>
Example Safe utilization of the cycle method when it may be utilized more than once on a pageDemonstrates a potential issue when using the cycle method more than once on a page without specifying a name for the cycle options, as well as how to correct it.

Broken Template

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="right">item</li> <li class="left">item</li></ul>

When the cycle method is used without a name, then future uses of the cycle method with the same options will resume where the first cycle group left off, which may lead to unexpected results.

Fixed Template

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'firstlist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'secondlist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="left">item</li> <li class="center">item</li></ul>

When the cycle method is used with a name, then the name is used instead of the options when determing the next option to output, which makes the results more consistent and predictable - particularly if the same options may be used by more than one cycle method.

Intentional Continuation of the Cycle

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'continuelist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'continuelist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="right">item</li> <li class="left">item</li></ul>

To intentionally resume a cycle method from the last option of a previous cycle method, use the same name and options.

Intentional Continuation of the Cycle with Different Options

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'continuelist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'continuelist': 'start', 'justify', 'end' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="end">item</li> <li class="start">item</li></ul>

Using the same name for multiple cycle methods with different options will resume from the index of the last option of the previous cycle method, but will use the options from the current cycle method.

Breaking the Cycle with Different Options

Liquid
{%- var cycleoptions = "'left', 'center', 'right'" %}<ul>
	{%- for item in list1 -%}
		<li class="{% cycle 'namedlist': *cycleoptions %}">{{ item }}</li>
		{%- set cycleoptions = "'start', 'end'" -%}
	{%- endfor -%}
</ul>
<ul>
	{%- for item in list2 -%}
		<li class="{% cycle 'namedlist': 'alpha', 'beta', 'gamma', 'delta' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul> <li class="left">item</li> <li class="end">item</li> ... </ul> <ul class="secondlist"> <li class="??">item</li> ...</ul>

While it is possible to change the options of a cycle method mid-cycle, or the options of a named cycle in between uses, it is not generally recommended as it results in code that is difficult to understand and maintain and is likely to produce unexpected output. It is particularly not recommended to change the number of options mid-cycle OR between uses of the same named cycle.

{{ forloop }}

Properties
Properties of {{ forloop }} objects
Name Type Description
name string The name of the current forloop (automatically generated from the for tag's variable and collection names).
length number The number of items in the forloop
index number The 1-based index of the current item in the for loop.
index0 number The 0-based index of the current item in the for loop.
rindex number The 1-based index of the current item in the for loop counting from the end to the beginning (the reverse of index).
rindex0 number The 0-based index of the current item in the for loop counting from the end to the beginning (the reverse of index0).
first boolean True if the current item is the first item in the for loop.
last boolean True if the current item is the last item in the for loop.
Example Loop over a collection and use forloop propertiesLoop over a collection and use forloop properties (first, last, index, length, etc.) for conditional output.
Liquid
{%- for item in collection -%}
	<div class="item-{{forloop.index0}}{% if forloop.first %} first{% elsif forloop.last %} last{% endif %} {% cycle forloop.name: "even", "odd" %}">
		<span class="itemcount">Item {{forloop.index}} out of {{forloop.length}}</span><br />
		<span class="itemvalue">{{ item }}</span><br />
		<span class="itemsleft">{{forloop.rindex0}} items remaining</span>
	</div>
{%- endfor -%}
Example How to use the for method

Basic: iterate through a collection

Liquid
{%- for item in collection -%}
	{{ item }}
{%- endfor -%}

This example will iterate through the collection and output each item.

Use the forloop variables to access loop properties

Liquid
{%- for item in collection -%}
	<span class="index-{{ forloop.index0 }}{% if forloop.first %} first{% elsif forloop.last %} last{% endif %}">Item {{ forloop.index }} out of {{ forloop.length }}</span>
{%- endfor -%}

You can use the automatically generated forloop variable to access loop properties like index, first, last, length, and more.

Watch out for nested forloop variables

Liquid
{%- for outer in collection1 -%}
	{%- for inner in collection2 -%}
		Outer Item #{{ forloop.index }}
	{%- endfor -%}
{%- endfor -%}

Note that you cannot access the outer forloop variable from within the inner forloop. This example will output the inner forloop index, not the outer forloop index.

Correcting access to nested forloop variables

Liquid
{%- for outer in collection1 -%}
	{%- var outerloop = forloop -%}{%- for inner in collection2 -%}
		Outer Item #{{ outerloop.index }}
	{%- endfor -%}
{%- endfor -%}

To access the outer forloop from within an inner loop you can store the outer forloop variable in a new variable with a different name and then access it using the new variable.

For loop with limit, and the continue keyword

Liquid
{%- var mycollection = (1..6) -%}
First Three: {% for item in mycollection limit:3 -%}
	<span class="index-{{forloop.index0}}{% if forloop.first %} first{% endif %}{% if forloop.last %} last{% endif %}">{{item}}</span>
{%- endfor %}
The Rest: {% for item in mycollection offset:continue -%}
	<span class="index-{{forloop.index0}}{% if forloop.first %} first{% endif %}{% if forloop.last %} last{% endif %}">{{item}}</span>
{%- endfor -%}
Output
First Three: <span class="index-0 first">1</span><span class="index-1">2</span><span class="index-2 last">3</span>
The Rest: <span class="index-0 first">4</span><span class="index-1">5</span><span class="index-2 last">6</span>

This example breaks a single collection into two separate loops using the limit and continue arguments. Note that the forloop variables (first, last, index, etc.) are reset for each loop.

For loop reversed

Liquid
{%- for number in (1..10) reversed -%}
	{%- if number == 9 -%}
		{%- continue -%}
	{%- elseif number == 6 -%}
		{%- break -%}
	{%- endif -%}
	<span class="index-{{forloop.index0}} {% if forloop.first %}first {% endif %}{% if forloop.last %}last {% endif %}{% cycle exampleclasses:'even', 'odd' %}">{{number}}</span>
{%- endfor -%}
Output
<span class="index-0 first even">10</span><span class="index-2 odd">8</span><span class="index-3 even">7</span>

This example reverses the list before looping through it. Note that the list is reversed BEFORE looping through it, so the indexes may appear to be in reverse order but they are not. Also note that the continue and break keywords work as expected and do not affect the forloop.first and forloop.last properties.

For loop with numeric offset

Liquid
{%- var items = (1..8) -%}
Skip first 2: {% for item in items offset:2 -%}
	{%- unless forloop.first %} {% endunless %}{{ item }}
{%- endfor -%}
Output
Skip first 2: 3 4 5 6 7 8

Use a numeric offset to skip the first N items in the collection. Here offset:2 skips 1 and 2, so the loop outputs 3 through 8.

Example Display linked titles from a list of itemsMap a collection of entities into a human-readable list of titles linking to the entities.
Liquid
{%- for entity in collection.items -%}
	{%- unless forloop.first or forloop.length == 2 %},{% unless forloop.last %} {% endunless %}{% endunless %}{% if forloop.last %}and{% endif %} {{ entity.linked_title -}}
{%- else -%}
	(none)
{%- endfor -%}

{% ifchanged %}

Executes a block of code, but only outputs it to the template if it results in a different string than the previous time that it was called with the same name.

{% ifchanged name %}
Parameters
name optionalvariable
Optional, but recommended. A semi-unique name which, when specified, allows the template to use the multiple groups of ifchanged methods simultaneously without replacing the results of the previous call for other groups. May use a reference variable to specify a dynamic name
{% endifchanged %}

This method creates a new liquid context for storing and manipulating variables.

All calls to ifchanged with no name act as one group. That is, they do not consider the results of calls to ifchanged that have a name specified.

Example Output only when a value changes (ifchanged tag)Use the ifchanged tag to output content only when a value has changed from the previous iteration.
Liquid
{%- var list = "1,3,2,1,3,1,2" | split: "," | sort -%}
{%- for item in list -%}
	{%- ifchanged %} {{ item }}{% endifchanged -%}
{%- endfor -%}
Output
 1 2 3

{% cycle %}

Cycles through a list of strings, returning the next value on each call. Cycle is typically called inside a for loop.

{% cycle [name:]? options %}
Parameters
name: optionalstring
A name for the cylcle to create an independent cycle group. Must be followed by a colon or else it may be confused with the options. If multiple cycles have the same name, they will share an index (so the second cycle will pick up where the first cycle left off). If the cycle does not have a name, one will automatically be created for it based on the options provided
options requiredlist
One or more values. May use the variable arguments syntax. The list of strings to cycle through

If you use multiple non-named cycles in your templates, you may end up with unexpected results. To prevent this, we recommend that you always name your cycle groups.

Example Cycle through values in a loop (cycle tag)Cycle through a list of values (e.g. CSS classes or colors) on each loop iteration with the cycle tag.
Liquid
<ul>
	{%- for item in list -%}
		<li class="{% cycle 'listposition': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Example Loop over a collection and use forloop propertiesLoop over a collection and use forloop properties (first, last, index, length, etc.) for conditional output.
Liquid
{%- for item in collection -%}
	<div class="item-{{forloop.index0}}{% if forloop.first %} first{% elsif forloop.last %} last{% endif %} {% cycle forloop.name: "even", "odd" %}">
		<span class="itemcount">Item {{forloop.index}} out of {{forloop.length}}</span><br />
		<span class="itemvalue">{{ item }}</span><br />
		<span class="itemsleft">{{forloop.rindex0}} items remaining</span>
	</div>
{%- endfor -%}
Example How to use the for method

Basic: iterate through a collection

Liquid
{%- for item in collection -%}
	{{ item }}
{%- endfor -%}

This example will iterate through the collection and output each item.

Use the forloop variables to access loop properties

Liquid
{%- for item in collection -%}
	<span class="index-{{ forloop.index0 }}{% if forloop.first %} first{% elsif forloop.last %} last{% endif %}">Item {{ forloop.index }} out of {{ forloop.length }}</span>
{%- endfor -%}

You can use the automatically generated forloop variable to access loop properties like index, first, last, length, and more.

Watch out for nested forloop variables

Liquid
{%- for outer in collection1 -%}
	{%- for inner in collection2 -%}
		Outer Item #{{ forloop.index }}
	{%- endfor -%}
{%- endfor -%}

Note that you cannot access the outer forloop variable from within the inner forloop. This example will output the inner forloop index, not the outer forloop index.

Correcting access to nested forloop variables

Liquid
{%- for outer in collection1 -%}
	{%- var outerloop = forloop -%}{%- for inner in collection2 -%}
		Outer Item #{{ outerloop.index }}
	{%- endfor -%}
{%- endfor -%}

To access the outer forloop from within an inner loop you can store the outer forloop variable in a new variable with a different name and then access it using the new variable.

For loop with limit, and the continue keyword

Liquid
{%- var mycollection = (1..6) -%}
First Three: {% for item in mycollection limit:3 -%}
	<span class="index-{{forloop.index0}}{% if forloop.first %} first{% endif %}{% if forloop.last %} last{% endif %}">{{item}}</span>
{%- endfor %}
The Rest: {% for item in mycollection offset:continue -%}
	<span class="index-{{forloop.index0}}{% if forloop.first %} first{% endif %}{% if forloop.last %} last{% endif %}">{{item}}</span>
{%- endfor -%}
Output
First Three: <span class="index-0 first">1</span><span class="index-1">2</span><span class="index-2 last">3</span>
The Rest: <span class="index-0 first">4</span><span class="index-1">5</span><span class="index-2 last">6</span>

This example breaks a single collection into two separate loops using the limit and continue arguments. Note that the forloop variables (first, last, index, etc.) are reset for each loop.

For loop reversed

Liquid
{%- for number in (1..10) reversed -%}
	{%- if number == 9 -%}
		{%- continue -%}
	{%- elseif number == 6 -%}
		{%- break -%}
	{%- endif -%}
	<span class="index-{{forloop.index0}} {% if forloop.first %}first {% endif %}{% if forloop.last %}last {% endif %}{% cycle exampleclasses:'even', 'odd' %}">{{number}}</span>
{%- endfor -%}
Output
<span class="index-0 first even">10</span><span class="index-2 odd">8</span><span class="index-3 even">7</span>

This example reverses the list before looping through it. Note that the list is reversed BEFORE looping through it, so the indexes may appear to be in reverse order but they are not. Also note that the continue and break keywords work as expected and do not affect the forloop.first and forloop.last properties.

For loop with numeric offset

Liquid
{%- var items = (1..8) -%}
Skip first 2: {% for item in items offset:2 -%}
	{%- unless forloop.first %} {% endunless %}{{ item }}
{%- endfor -%}
Output
Skip first 2: 3 4 5 6 7 8

Use a numeric offset to skip the first N items in the collection. Here offset:2 skips 1 and 2, so the loop outputs 3 through 8.

Example Safe utilization of the cycle method when it may be utilized more than once on a pageDemonstrates a potential issue when using the cycle method more than once on a page without specifying a name for the cycle options, as well as how to correct it.

Broken Template

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="right">item</li> <li class="left">item</li></ul>

When the cycle method is used without a name, then future uses of the cycle method with the same options will resume where the first cycle group left off, which may lead to unexpected results.

Fixed Template

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'firstlist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'secondlist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="left">item</li> <li class="center">item</li></ul>

When the cycle method is used with a name, then the name is used instead of the options when determing the next option to output, which makes the results more consistent and predictable - particularly if the same options may be used by more than one cycle method.

Intentional Continuation of the Cycle

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'continuelist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'continuelist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="right">item</li> <li class="left">item</li></ul>

To intentionally resume a cycle method from the last option of a previous cycle method, use the same name and options.

Intentional Continuation of the Cycle with Different Options

Liquid
<ul class="firstlist">
	{%- for item in list limit:2 -%}
		<li class="{% cycle 'continuelist': 'left', 'center', 'right' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
<ul class="secondlist">
	{%- for item in list offset:continue -%}
		<li class="{% cycle 'continuelist': 'start', 'justify', 'end' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul class="firstlist"> <li class="left">item</li> <li class="center">item</li> </ul> <ul class="secondlist"> <li class="end">item</li> <li class="start">item</li></ul>

Using the same name for multiple cycle methods with different options will resume from the index of the last option of the previous cycle method, but will use the options from the current cycle method.

Breaking the Cycle with Different Options

Liquid
{%- var cycleoptions = "'left', 'center', 'right'" %}<ul>
	{%- for item in list1 -%}
		<li class="{% cycle 'namedlist': *cycleoptions %}">{{ item }}</li>
		{%- set cycleoptions = "'start', 'end'" -%}
	{%- endfor -%}
</ul>
<ul>
	{%- for item in list2 -%}
		<li class="{% cycle 'namedlist': 'alpha', 'beta', 'gamma', 'delta' %}">{{ item }}</li>
	{%- endfor -%}
</ul>
Output
<ul> <li class="left">item</li> <li class="end">item</li> ... </ul> <ul class="secondlist"> <li class="??">item</li> ...</ul>

While it is possible to change the options of a cycle method mid-cycle, or the options of a named cycle in between uses, it is not generally recommended as it results in code that is difficult to understand and maintain and is likely to produce unexpected output. It is particularly not recommended to change the number of options mid-cycle OR between uses of the same named cycle.

{% include %}

Processes and outputs a partial template, javascript, or stylesheet. If the partial template is a compiled template, then any custom fields from the partial template will be available in the parent template as well.

{% include [template|javascript|stylesheet]? variable =? attributes? %}
Parameters
type optionalstring
Explicit type selector: template, javascript, or stylesheet. If not specified, the object to be included will be the same as the type of the current ojbect (in a template this will default to template, etc...).
variable requiredobject
May be the template, javascript, or stylesheet object to include, the unique identifier for the object to include, or the relative or absolte path to the template, javascript, or stylesheet
attributes optionaldictionary
Key:value pairs with unique keys. May use the variable arguments syntax. Variables to set on the created scope before the included object is processed

This method creates a new liquid context for storing and manipulating variables.

The path is significant when including objects. Every template, javascript, and stylesheet has a path, even if that is the "root path" (/). The location of the path to be included will always be based off of the path of the current object. So including 'header' from a template at the path '/pages' will attempt to process '/pages/header' while the same include from a template at the root path - which would attempt to process '/header'. You always have the option of using an "absolute path" when including templates by beginning your included template name with '/'. Eg: {% include '/header' %} or {% include '/partials/header' %}. Absolute paths ignore the path of the current template when determining what partial to include. You can also navigate up the directory structure using '../'. So including '../partials/header' from a template at the path '/agency/pages' will attempt to process '/agency/partials/header'.

Example Capturing markup and passing it to an included templateCapture a block of markup with the capture tag and pass it to an included template as a variable.
Liquid
{%- capture blockContent -%}
	<div class="block-outer">
		<h3 class="block-title">
			{%- if article.default_page_url.is_valid -%}
				<a href="{{article.default_page_url.value}}">{{article.title}}</a>
			{%- else -%}
				{{-article.title-}}
			{%- endif -%}
		</h3>
		<div class="block-description">{{article.summary_html}}</div>
		<div class="block-footer">Posted {{article.post_date}}</div>
	</div>
{%- endcapture -%}
{%- include "_block_outer" content:blockContent -%}
Example Checkbox Include Partial TemplateInclude a partial template conditionally when a checkbox (or other) field is checked.
Liquid
<p>Show Sidebar? <strong>{{ page.show_sidebar }}</strong></p>
{%- if page.show_sidebar.checked -%}
	{%- include "Sidebar" -%}
{%- endif -%}
Example Include a template whose name is in a variableDemonstrates multple ways to dynamically include a template. Note that in all of these examples, the template fields will NOT be compiled in the page definition.

Dynamically Include a Template from a Variable

Liquid
{%- var dynamicTemplate = "/partials/footer-main.liquid" -%}
{%- include dynamicTemplate -%}

Dynamically Include Template from a Select List

Liquid
{%- if page.page_layout.is_valid -%}
	<div class="sidebar-{{ page.page_layout.value }}">
		{%- var includeTemplate = "/theme/sidebar/" | append:page.page_layout.value -%}
		{%- include includeTemplate -%}
	</div>
{%- endif -%}

Assuming that page_layout is a select field or similar, this code dynamically creates the name of the template to include based on the selected value.

Dynamically Include Multiple Templates from a TemplateList Field

Liquid
{%- if page.sidebar_sections.count > 0 -%}
	{%- for section in page.sidebar_sections.selected -%}
		{%- include section -%}
	{%- endfor -%}
{%- endif -%}

Assuming that sidebar_sections is a templatelist field or similar, this code dynamically includes each of the selected templates.

Check if a dynamic template exists before including it

Liquid
{%- template var dynamicTemplate = "/theme/sidebar/" | append: page.sidebar_section.value | append: ".liquid" -%}
{%- if dynamicTemplate.is_valid -%}
	{%- include dynamicTemplate -%}
{%- endif -%}

Assuming that sidebar_sections is a templatelist field or similar, this code dynamically includes each of the selected templates.

Example How to use the {% include %} method

Basic use case

Liquid
{% include "/_header.liquid" %}

Includes the partial template from the specified path. This is the simplest way to include a partial template.

Include partial by string with attributes

Liquid
{% include "/sections/_banner.liquid" section_class:'banner-section mb-5' show_title:true show_description:false %}

Includes the partial template from the specified path. The new scope created by the include method will have the specified attributes available as variables.

Expanded example with relative and absolute paths

Liquid
{%- search searchCollection "keyword" limit:10 page:search-page -%}
{%- for result in searchCollection -%}
	{%- include "./search-result.liquid" item:result -%}
{%- endfor -%}
{%- include "/shared/_pagination.liquid" collection:searchCollection style:"links" max_links:5 -%}

Includes the partial template from the specified path. The relative path is relative to the current template, and the absolute path is relative to the root of the website.

Example Inline javascript from templateOutput inline JavaScript from template variables (e.g. for config or data) with proper escaping.
Liquid
<script>{% include javascript "/javascript/inlined/blog" %}</script>
OR
{%- javascript js = "/javascript/inlined/blog" -%}
{%- if js is_valid -%}
<script>{% include js %}</script>
{%- endif -%}
Example Include sidebar template unless a query param is falseInclude a sidebar template only when a query parameter is not false, using unless.
Liquid
{%- unless request.query_params contains "show_sidebar=false" -%}
	{%- if request.query_params has_key "show_sidebar" -%}
		{%- include "_custom_sidebar" type:request.query_params.show_sidebar -%}
	{%- else -%}
		{%- include "_default_sidebar" type:request.query_params.show_sidebar -%}
	{%- endif -%}
{%- endunless -%}