{% assign %}
Stores a value to a variable on the root scope.
Methods that create and store variables, including map and dictionary helpers.
Stores a value to a variable on the root scope.
Var sets the value on the current scope
{{ test1 }}
{%- var test1 = 'out1' -%}
,{{ test1 }}
{%- if true -%}
,{{ test1 }}
{%- var test1 = 'out2' -%}
,{{ test1 }}
{%- endif -%}
,{{ test1 }},out1,out1,out2,out1
The first time the variable is output it has not been set yet so it does not output anything. The second time it has been set to out1. The third time it has not been set on the current scope but it is still set on the parent scope so it outputs out1 again. The next time it has been set to out2 on the current scope so that is output instead. When the current scope ends (with the endif method) the variable is still set on the parent scope so it outputs out1 again.
Set changes the value on the closest scope
{%- var test2 = 'out1' -%}
{{ test2 }}
{%- if true -%}
{%- var test2 = 'out2' -%}
,{{ test2 }}
{%- set test2 = 'out3' -%}
,{{ test2 }}
{%- if true -%}
{%- set test2 = 'out4' -%}
,{{ test2 }}
{%- endif -%}
,{{ test2 }}
{%- endif -%}
,{{ test2 }}out1,out2,out3,out4,out4,out1
The first time the variable is output it has been set to out1 on the root scope. The second time it has been set to out2 on the current scope using the var method so it is still unchanged on the root scope. The third time it has been updated to out3 on the nearest scope that it is defined for, which also happens to be the current scope. The fourth time it has been updated to out4 on the parent scope, which is the nearest scope that it is defined for. When the current scope ends and returns to the parent scope, the updated value is still present. When that scope ends and it returns to the root scope, the variable returns to the value that was set on the root scope.
Assign sets the value on the root scope and removes the variable from all other scope
{{ test3 }}
{%- if true -%}
{%- var test3 = 'out1' -%}
,{{ test3 }}
{%- if true -%}
{%- assign test3 = 'out2' -%}
,{{ test3 }}
{%- endif -%}
,{{ test3 }}
{%- endif -%}
,{{ test3 }},out1,out2,out2,out2
The first time the variable is output it has not been set yet so it does not output anything. The second time it has been set to out1 on the current scope (not the root scope). The third time it has been set to out2 on the root scope by the assign method, which also clears it from all other scopes. Then the fourth and fifth times it outputs out2 from the root scope.
Store a value in a variable using a filter
{%- var title = entity.name | default: 'Untitled' -%}
<p>{{ title }}</p>Stores the result of the expression in a variable for reuse.
Create an empty variable, then update it as needed using the set method
{%- var tag = '' -%}
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- set tag=entity.tags | first -%}
{%- endif -%}
{%- datastore_items datastore:"products" tag:tag -%}Conditionally stores the first tag in the tags list in the tag variable. Then uses the tag variable to filter the datastore items. Using var and set in this way prevents the tag variable from being overwritten in the parent scope.
Duplicate a variable, then update it as needed to preserve the original value
{%- var tag = tag -%}
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- set tag=entity.tags | first -%}
{%- endif -%}
{%- datastore_items datastore:"products" tag:tag -%}By creating a new variable on the current scope from an existing variable on the parent scope, we can update the variable using the set method without affecting the parent scope. Note that even if the variable is not set on the parent scope the current scope will still define the variable with a null value.
Use assign to force the variable to be accessible from the root scope
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- assign num_tags = entity.tags | size -%}
{%- endif -%}
There are {{num_tags | default:0}} tags on this entityThe assign method creates a root-scope variable, so it is accessible from the root scope and all child scopes.
Stores a value to a variable on the current scope.
<!-- This example uses a unicode variant of angle brackets (<>) to prevent the characters being escaped.
You will want to replace the angle brackets if you intend to copy/paste this example. -->
{%- var tagtype = "div" -%}
〈{{tagtype}}〉
{%- if true -%}
{%- var tagtype = "span" -%}
〈{{tagtype}}〉Some Content 〈/{{tagtype}}〉
{%- endif -%}
〈/{{tagtype}}〉{%- var minDate = "now" | midnight -%}
{%- var maxDate = "now" | midnight | add_months: 1 -%}
{%- calendar_entries var entries = start_date:minDate end_date:maxDate limit:30 sort_by:"start_date" sort_direction:"asc" -%}Var sets the value on the current scope
{{ test1 }}
{%- var test1 = 'out1' -%}
,{{ test1 }}
{%- if true -%}
,{{ test1 }}
{%- var test1 = 'out2' -%}
,{{ test1 }}
{%- endif -%}
,{{ test1 }},out1,out1,out2,out1
The first time the variable is output it has not been set yet so it does not output anything. The second time it has been set to out1. The third time it has not been set on the current scope but it is still set on the parent scope so it outputs out1 again. The next time it has been set to out2 on the current scope so that is output instead. When the current scope ends (with the endif method) the variable is still set on the parent scope so it outputs out1 again.
Set changes the value on the closest scope
{%- var test2 = 'out1' -%}
{{ test2 }}
{%- if true -%}
{%- var test2 = 'out2' -%}
,{{ test2 }}
{%- set test2 = 'out3' -%}
,{{ test2 }}
{%- if true -%}
{%- set test2 = 'out4' -%}
,{{ test2 }}
{%- endif -%}
,{{ test2 }}
{%- endif -%}
,{{ test2 }}out1,out2,out3,out4,out4,out1
The first time the variable is output it has been set to out1 on the root scope. The second time it has been set to out2 on the current scope using the var method so it is still unchanged on the root scope. The third time it has been updated to out3 on the nearest scope that it is defined for, which also happens to be the current scope. The fourth time it has been updated to out4 on the parent scope, which is the nearest scope that it is defined for. When the current scope ends and returns to the parent scope, the updated value is still present. When that scope ends and it returns to the root scope, the variable returns to the value that was set on the root scope.
Assign sets the value on the root scope and removes the variable from all other scope
{{ test3 }}
{%- if true -%}
{%- var test3 = 'out1' -%}
,{{ test3 }}
{%- if true -%}
{%- assign test3 = 'out2' -%}
,{{ test3 }}
{%- endif -%}
,{{ test3 }}
{%- endif -%}
,{{ test3 }},out1,out2,out2,out2
The first time the variable is output it has not been set yet so it does not output anything. The second time it has been set to out1 on the current scope (not the root scope). The third time it has been set to out2 on the root scope by the assign method, which also clears it from all other scopes. Then the fourth and fifth times it outputs out2 from the root scope.
Store a value in a variable using a filter
{%- var title = entity.name | default: 'Untitled' -%}
<p>{{ title }}</p>Stores the result of the expression in a variable for reuse.
Create an empty variable, then update it as needed using the set method
{%- var tag = '' -%}
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- set tag=entity.tags | first -%}
{%- endif -%}
{%- datastore_items datastore:"products" tag:tag -%}Conditionally stores the first tag in the tags list in the tag variable. Then uses the tag variable to filter the datastore items. Using var and set in this way prevents the tag variable from being overwritten in the parent scope.
Duplicate a variable, then update it as needed to preserve the original value
{%- var tag = tag -%}
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- set tag=entity.tags | first -%}
{%- endif -%}
{%- datastore_items datastore:"products" tag:tag -%}By creating a new variable on the current scope from an existing variable on the parent scope, we can update the variable using the set method without affecting the parent scope. Note that even if the variable is not set on the parent scope the current scope will still define the variable with a null value.
Use assign to force the variable to be accessible from the root scope
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- assign num_tags = entity.tags | size -%}
{%- endif -%}
There are {{num_tags | default:0}} tags on this entityThe assign method creates a root-scope variable, so it is accessible from the root scope and all child scopes.
Replaces a value on the nearest scope where it has already been defined. If it has not been defined yet, it is stored on the root scope.
Var sets the value on the current scope
{{ test1 }}
{%- var test1 = 'out1' -%}
,{{ test1 }}
{%- if true -%}
,{{ test1 }}
{%- var test1 = 'out2' -%}
,{{ test1 }}
{%- endif -%}
,{{ test1 }},out1,out1,out2,out1
The first time the variable is output it has not been set yet so it does not output anything. The second time it has been set to out1. The third time it has not been set on the current scope but it is still set on the parent scope so it outputs out1 again. The next time it has been set to out2 on the current scope so that is output instead. When the current scope ends (with the endif method) the variable is still set on the parent scope so it outputs out1 again.
Set changes the value on the closest scope
{%- var test2 = 'out1' -%}
{{ test2 }}
{%- if true -%}
{%- var test2 = 'out2' -%}
,{{ test2 }}
{%- set test2 = 'out3' -%}
,{{ test2 }}
{%- if true -%}
{%- set test2 = 'out4' -%}
,{{ test2 }}
{%- endif -%}
,{{ test2 }}
{%- endif -%}
,{{ test2 }}out1,out2,out3,out4,out4,out1
The first time the variable is output it has been set to out1 on the root scope. The second time it has been set to out2 on the current scope using the var method so it is still unchanged on the root scope. The third time it has been updated to out3 on the nearest scope that it is defined for, which also happens to be the current scope. The fourth time it has been updated to out4 on the parent scope, which is the nearest scope that it is defined for. When the current scope ends and returns to the parent scope, the updated value is still present. When that scope ends and it returns to the root scope, the variable returns to the value that was set on the root scope.
Assign sets the value on the root scope and removes the variable from all other scope
{{ test3 }}
{%- if true -%}
{%- var test3 = 'out1' -%}
,{{ test3 }}
{%- if true -%}
{%- assign test3 = 'out2' -%}
,{{ test3 }}
{%- endif -%}
,{{ test3 }}
{%- endif -%}
,{{ test3 }},out1,out2,out2,out2
The first time the variable is output it has not been set yet so it does not output anything. The second time it has been set to out1 on the current scope (not the root scope). The third time it has been set to out2 on the root scope by the assign method, which also clears it from all other scopes. Then the fourth and fifth times it outputs out2 from the root scope.
Store a value in a variable using a filter
{%- var title = entity.name | default: 'Untitled' -%}
<p>{{ title }}</p>Stores the result of the expression in a variable for reuse.
Create an empty variable, then update it as needed using the set method
{%- var tag = '' -%}
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- set tag=entity.tags | first -%}
{%- endif -%}
{%- datastore_items datastore:"products" tag:tag -%}Conditionally stores the first tag in the tags list in the tag variable. Then uses the tag variable to filter the datastore items. Using var and set in this way prevents the tag variable from being overwritten in the parent scope.
Duplicate a variable, then update it as needed to preserve the original value
{%- var tag = tag -%}
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- set tag=entity.tags | first -%}
{%- endif -%}
{%- datastore_items datastore:"products" tag:tag -%}By creating a new variable on the current scope from an existing variable on the parent scope, we can update the variable using the set method without affecting the parent scope. Note that even if the variable is not set on the parent scope the current scope will still define the variable with a null value.
Use assign to force the variable to be accessible from the root scope
{%- if entity.tags is_list and entity.tags.is_valid -%}
{%- assign num_tags = entity.tags | size -%}
{%- endif -%}
There are {{num_tags | default:0}} tags on this entityThe assign method creates a root-scope variable, so it is accessible from the root scope and all child scopes.
Captures rendered output as a string into a variable.
{% endcapture %}{%- 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 -%}{%- capture page_description -%}
{{- page.browser_title }} | {{ site.name }}:
{%- unless page.browser_title contains entity.title -%}
[{{ entity.title }}]
{%- endunless -%}
{{- page.meta_description | truncate: 50 '...' -}}
{%- endcapture -%}
The page description is "{{ page_description | escape }}"Increments a variable by one and then outputs it to the template.
If the variable does not exist yet, it will be created with an initial value of 0 (1 after incrementing). If the vartype (var, set, or assign) is not set, this method uses a default vartype of "set" (ie: the current variable will be updated, and if the variable does not exist yet it will be created at the root scope).
increment with no initial value
{{ counter | default:'N/A'}} {% increment counter %} {% increment counter %} {% increment counter %} {{counter | default:'N/A'}}N/A 1 2 3 3
Outputs the value after each increment. If the variable does not exist, it starts at 0, so the first output is 1, then 2, then 3.
decrement with no initial value
{{ counter | default:'N/A'}} {% decrement counter %} {% decrement counter %} {% decrement counter %} {{counter | default:'N/A'}}N/A -1 -2 -3 -3
Outputs the value after each decrement. Starts at 0, so first output is -1, then -2, then -3.
increment without outputting the value
{{ counter | default: 'N/A'}} {% set counter = counter | to_number | default: 0 | plus: 1 %} {{ counter | default: 'N/A'}}N/A 1
To update a variable without outputting, use set with the plus/minus filter instead of the increment/decrement tags. You may need to use the to_number and default filters to ensure the variable is a number before adding or subtracting if you do not already know that it is a number.
Decrements a variable by one and then outputs it to the template.
If the variable does not exist yet, it will be created with an initial value of 0 (-1 after decrementing). If the vartype (var, set, or assign) is not set, this method uses a default vartype of "set" (ie: the current variable will be updated, and if the variable does not exist yet it will be created at the root scope).
increment with no initial value
{{ counter | default:'N/A'}} {% increment counter %} {% increment counter %} {% increment counter %} {{counter | default:'N/A'}}N/A 1 2 3 3
Outputs the value after each increment. If the variable does not exist, it starts at 0, so the first output is 1, then 2, then 3.
decrement with no initial value
{{ counter | default:'N/A'}} {% decrement counter %} {% decrement counter %} {% decrement counter %} {{counter | default:'N/A'}}N/A -1 -2 -3 -3
Outputs the value after each decrement. Starts at 0, so first output is -1, then -2, then -3.
increment without outputting the value
{{ counter | default: 'N/A'}} {% set counter = counter | to_number | default: 0 | plus: 1 %} {{ counter | default: 'N/A'}}N/A 1
To update a variable without outputting, use set with the plus/minus filter instead of the increment/decrement tags. You may need to use the to_number and default filters to ensure the variable is a number before adding or subtracting if you do not already know that it is a number.
Creates a "unique" identifier each time it is called. Each identifier consists only of lowercase letters, and each subsequent call simply increments it by 1 character (ie: 'aaa' -> 'aab' -> 'aac', etc...). Identifiers created using this method are not random and therefore will not prevent caching. However, if the number of times the id method is called or if the arguments to the id method is changed the identifiers may not be consistent between page loads - which means that you should not rely on identifiers created using this method for styling or for creating sharable links.
Simple Use Case
<form id="{% id %}">Every time the id method is used, it will generate a new semi-unique identifier. The id method will never produce the same identifier multiple times in the same pageload. If the generated identifier is not saved in a variable, it will be output directly to the template.
Long Id
<div id="{% id = length:32 suffix:'_longidentifier' %}">The length option specifies the length of the id to generate - in this example 32 characters. The maximum allowed value for the length parameter is 36 characters. The suffix option appends the specified string to the end of the id.
Short Id
<div id="{% id = length:1 prefix:'myid_' %}">The length option specifies the length of the id to generate - in this example 1 character. The prefix option prepends the specified string before the generated id.
Skip Id
<div id="{% id = skip:'ffffffff' suffix:'_images' %}">
{%- for image in entity.images -%}
<div id="{% id var image_id output_to_template = length:8 prefix:'img_' %}">...</div>
{%- endfor -%}
</div>The skip option specifies the id to skip past - in this example 'ffffffff'. Note that for the following ids to continue past the skipped id, the length parameter must be set to the correct value. The skip option is mostly useful when you need to generate unique ids for partial html content to be loaded using javascript.
Save Id
<form id="{% id var form_id output_to_template = prefix:'myform_' %}">...</form>
<script type="text/javascript">var myform = document.getElementById('{{form_id}}'); ...</script>It is often useful to save the generated id to a variable so that it can be used in later template code, such as in javascript initialization code. This may also be combined with the output_to_template option to output the id to the template as well as store it in the specified variable.
Creates a new list of strings from the output when a block of liquid markup is executed for each item in a list or collection.
This method behaves exactly the same as the {% for %} method, except that instead of outputting the results directly to the template, it saves them in a list instead. It may be helpful to think of the map method as the capture method for lists. You can even assign variables by reference (eg: {% map &newcollection for item in oldcollection %}). Note that you can also use the forloop properties and tags inside a map block (see the {% for %} method documentation for details).
{%- map assign post_html for post in blogposts -%}
<h3>{{ post.linked_title }}</h3>
{%- if post.image.is_valid -%}
<p>{% img post.image link:post.default_page_url preset:"thumb" title:post.title %}</p>
{%- endif -%}
<div class="summary">{{ post.summary_html }}</div>
{%- endmap -%}
<div class="mainpost">{{post_html[0]}}</div>
{%- let smallcontent = post_html | slice: 1 -%}
{%- include "_small_content" contents:smallcontent -%}Creates a new editable dictionary with the given properties.
{%- create_dictionary pagination = limit:5 page:2 -%}
{%- create_dictionary sorting = sort_by:"post_date" sort_direction: "desc" -%}
{%- comment %}This will create a new dictionary if it does not already exist. Any previous filters may be overwritten from request.post_params.{% endcomment -%}
{%- copy_to_dictionary filters = request.post_params pagination sorting -%}
{%- comment %}If you use the new_only instruction then previous filters will not be overwritten.{% endcomment -%}
{%- create_dictionary filters = blog:entity.blog_main tag:entity.tag_filter -%}
{%- copy_to_dictionary filters = pagination sorting request.post_params new_only -%}{%- capture settings -%}
inputs: posts
number: 5
style: 'two-tone'
sortable: false
original_entity: entity
{%- endcapture -%}
{%- create_dictionary settings = *settings -%}
{{- settings | inspect }}Copies properties from one or more copyable objects (eg: dictionaries) into an editable dictionary. If the dictionary is not editable this will throw an error. If the dictionary does not exist then one will be created and saved on the current scope.
The following objects are copyable and can be used as arguments in the {% copy_to_dictionary %} method:
dictionary - will copy all of the dictionary properties from one dictionary to another
labels - will copy all of the key-value pairs from the labels field to the dictionary. If the labels field contains duplicate keys then only one of the values will be copied for that key.
profile - will copy all of the profile settings to the new dictionary
datastore_item - will copy all of the datastore fields to the new dictionary, along with the datastore item name (as a text object), title (as a text object), and folder (as a folder object) if it is in a folder
form_submit - will copy all of the form submission values (as their respective object types) to the new dictionary
client - will copy all of the client properties as strings to the new dictionary
cookies - will copy all of the cookies as strings to the new dictionary
request.headers - will copy all of the request headers as strings to the new dictionary
client_permissions - will copy all of the permissions (as permission objects) that have been specified for the client to the new dictionary - including both allowed and denied permissions
post_params - will copy all of the post parameters from the request to the new dictionary. Parameter values will either be strings or arrays (if the request had multiple post parameters with the same name).
query_params - will copy all of the query parameters (as strings) from the request to the new dictionary.
session - will copy all of the session properties as strings to the new dictionary
site - will copy all of the settings (as their respective object types) from the site to the new dictionary
{%- create_dictionary pagination = limit:5 page:2 -%}
{%- create_dictionary sorting = sort_by:"post_date" sort_direction: "desc" -%}
{%- comment %}This will create a new dictionary if it does not already exist. Any previous filters may be overwritten from request.post_params.{% endcomment -%}
{%- copy_to_dictionary filters = request.post_params pagination sorting -%}
{%- comment %}If you use the new_only instruction then previous filters will not be overwritten.{% endcomment -%}
{%- create_dictionary filters = blog:entity.blog_main tag:entity.tag_filter -%}
{%- copy_to_dictionary filters = pagination sorting request.post_params new_only -%}Sets properties on an editable dictionary object. If the dictionary does not exist it will be created and stored on the current scope. If the dictionary exists but is not editable this will throw an error.
{%- var inputname = 'inputs' -%}
{%- set_dictionary settings = &inputname:posts number:posts.size sortable:true -%}Removes properties from an editable dictionary object. If the dictionary does not exist an empty one will be created and stored on the current scope. If the dictionary exists but is not editable this will throw an error.
{%- capture unset_properties -%}
{{-inputname-}}
number
sortable
{%- endcapture -%}
{%- unset_dictionary settings *unset_properties style -%}