Built-in tags¶
Comments¶
Comments can be used to add documentation to your templates or "comment out" chunks of markup so that it wont be rendered.
You can safely comment out markup containing comments by adding hashes, as long as the number of hashes is balanced.
By convention, comments that start with a single hash on every line are considered doc comments to be parsed by a documentation generator.
Output¶
An expression surrounded by double curly braces ({{ and }}) is an output statement. When rendered, the expression will be evaluated and the result written to the output stream.
In this example the expression is the variable you - which will be resolved to a value and the value's string representation will be written to the output stream - but output statements can contain any expression.
assign¶
The assign tag binds the result of evaluating an expression to a name, creating or updating a variable.
A single assign tag can define multiple variables, separated by commas. Earlier bindings are immediately available in later expressions.
capture¶
The capture tag renders a block of markup to a string variable instead of writing it directly to the output stream.
{% assign first_name = "Sam" %}
{% assign points = 120 %}
{% capture message %}
Hello {{ first_name }}!
You have {{ points }} reward points.
{% endcapture %}
<p>{{ message }}</p>
See also the define tag.
case¶
{% case <expression> %}
[ {% when <expression | predicate> [, <expression | predicate>] %} <markup> ] ...
[ {% else %} <markup> ]
{% endcase %}
The case tag provides a multi-way conditional. It compares the result of a single expression against the result of one or more candidate expressions, and renders the block following the first matching {% when %} tag. If no branch matches, the optional {% else %} branch is rendered.
{% assign day = "Monday" %}
{% case day %}
{% when "Monday" %}
Start of the work week!
{% when "Friday" %}
It's almost the weekend!
{% when "Saturday" or "Sunday" %}
Enjoy your weekend!
{% else %}
Just another weekday.
{% endcase %}
when tags also understand bare predicates, like .defined? and .empty? in place of a standard expression.
define¶
The define tag captures a block of markup for later rendering. define captures nothing about the scope in which it rendered. Defined blocks are rendered in the scope in which they are output or coerced to a string.
{% assign name = "Alice" %}
{% define greeting %}
Hello {{ name }}!
{% enddefine %}
{% assign name = "Bob" %}
{{ greeting }}
{{ greeting | upcase }}
define can be though of as a deferred capture. See also import.
for¶
{% for <identifier> [, identifier [, identifier]] in <expression> %}
<markup>
[ {% else %} <markup> ]
{% endfor %}
The for tag renders its block once for each item in an iterable object. If the iterable is empty and an else block given, it will be rendered instead.
Optionally, the current zero-based iteration index can be bound to a name.
And the optional third identifier binds the array being iterated to a name.
{% for product, index, array in collection %}
{%- assign last = index == (array | size) - 1 -%}
...
{% endfor %}
break¶
You can exit a loop early using the break tag.
{% for product in collection.products %}
{% if product.title == "Shirt" %}
{% break %}
{% endif %}
- {{ product.title }}
{% endfor %}
continue¶
You can skip all or part of a loop iteration with the continue tag.
{% for product in collection.products %}
{% if product.title == "Shirt" %}
{% continue %}
{% endif %}
- {{ product.title }}
{% endfor %}
if¶
{% if <expression> %}
<markup>
[ {% elsif <expression> %} <markup> [ {% elsif <expression> %} ... ]]
[ {% else %} <markup> ... ]
{% endif %}
The if tag conditionally renders its block if its expression evaluates to be truthy. Any number of elsif blocks can be given to add alternative conditions, and an else block is used as a default if no preceding conditions were truthy.
{% if product.title == "OK Hat" %}
This hat is OK.
{% elsif product.title == "Rubbish Tie" %}
This tie is rubbish.
{% else %}
Not sure what this is.
{% endif %}
import¶
The import tag loads and renders a named template for its side effects, discarding its output. import is used to bring variables (including blocks defined with the define tag) into scope.
include¶
{% include <template name>
[[,] <identifier>: <expression> [, [<identifier>: <expression> ... ]]]
%}
The include tag loads and renders a named template, inserting the resulting text in its place. The name of the template to include can be a string literal or a variable resolving to a string. When rendered, the included template will share the same scope as the "calling" template.
Keyword arguments¶
Additional keyword arguments given to the include tag will be added to the included template's scope, then go out of scope after the included template has been rendered.
raw¶
Any text between {% raw %} and {% endraw %} will not be interpreted as markup, but output as plain text instead.
render¶
The render tag loads and renders a named template, inserting the resulting text in its place. The name of the template to include must be a string literal. When rendered, the included template will have its onw scope, without variables define in the calling template.
Keyword arguments¶
Additional keyword arguments given to the render tag will be added to the rendered template's scope, then go out of scope after the it has been rendered.
with¶
{% with <identifier> = <expression> [, <identifier> = <expression> ... ] %}
<markup>
{% endwith %}
The with tag introduces block-scoped variables. These variables have the potential to shadow global variables or variables assigned with {% assign %}, {% capture %} and {% define %}.
{% with p = collection.products.first %}
{{ p.title }}
{% endwith %}
{% with a = 1, b = 3.4 %}
{{ a }} + {{ b }} = {{ a + b }}
{% endwith %}
When multiple bindings are given, earlier variables are in scope for later expressions.