Documentation

Liquid Reference

In this article

Jim Dekker

Published: 16-10-2019

Last updated: 10-02-2020

Our template language, which is based on the Liquid open source project, uses a combination of tags, objects, and filters to merge dynamic content into templates. Templates can be used for web pages, e-mails, and pdf’s but also JSON or XML based files.

Basic usage

There are two types of markup in Liquid:

Output

The output markup is used by surrounding an expression by a set of double curly braces. Every output statement is expected to return text. 

Hello {{ name }}

Tag

The tag markup is used by matching pairs of curly brackets and percent signs. Tags are used for logic in your template and will not return text. 

{% comment %}

Variables

Variables are properties that can be saved and altered. Liquid templates can use variables in several places. Variables are mostly used in output statements but can also be used as arguments in tags or filters. Every type of variable can be accessed by using the name of the variable inside an output or tag markup.

{{ variable_name }}

Text

When using text this must be surrounded by quotes. It doesn’t matter if single or double quotes are used. 

{{ "text" }}

Numbers

Numbers used in either output or tag statements don’t need to be quoted.

{{ 8 }}

Booleans and nil

With these values,the literal values true, false, and nil can be used without surrounding quotes.

{{ false }}

Collections

A single item in a collection can be fetched by using the name of the collection, followed immediately by square brackets containing a key. This key must be a number or an expression where the outcome will become a number.

{{ collection[2] }}

Objects

The property of an object can be fetched by using the name of the object, followed by a period and the name of the property.

{{ object.property }}

Hash

The value of a hash can be fetched in multiple ways. The same ‘dot’ notation as with the objects can be used, or the name of the hash, followed by square brackets containing the key of the property. In this case, the key must be the name of the property surrounded by quotes.

{{ hash.property }}
{{ hash["property"] }}

Note: The syntax of fetching values of collections, objects and hashes can be combined if the fetch would result in another collection, object or hash.

{{ object.collection[5].property }}

Filters

Filters can be used to modify the result of a value within the output markup. A filter can be called by using a pipe character after the value that you want to have filtered. Filters can also be chained together by using another pipe character after the first filter. The output of the previous filter will be the input of the next one.

Hello {{ name | upcase }}
Five times four equals {{ 5 | times: 4 }}

Append

Adds the set text value after the value within the output markup.

{{ "Betty" | append: "Blocks" }} >>> BettyBlocks

Capitalize

Capitalizes text, making the first character of the text capital. Note that this command downcases the whole text first so that only the first character will be capital. 

{{ "capitalize me" | capitalize }} >>> Capitalize me

Ceil

Rounds a number with decimal up to the nearest number.

{{ 4.6 | ceil }} >>> 5

Date

Reformats a date by using special characters. With this filter it is also possible to convert text to a date property if the correct formatting is used on the text value. The supported date formats can be found here.

{{ "now" | date: "%a, %b %d, %y" }} >>> Fri, Apr 26, 19

Default

Returns the value within the output markup unless it is nil or an empty value, in which case it will return the set default value.

{{ nil | default: "This is default" }} >>> This is default

Divided_by

Divides a number by the set number value. The outcome will be rounded up to the nearest number.

{{ 23 | divided_by: 4 }} >>> 5

Downcase_first

Converts the first character of a text value to all lowercase characters.

{{ "UPPERCASE" | downcase_first }} >>> uPPERCASE

Downcase

Converts a text value to all lowercase characters.

{{ "THIS WAS UPPERCASE" | downcase  }} >>> this was uppercase

Escape_once

Converts HTML entities to their corresponding entity name without affecting characters that are already converted.

{{ "<html> &" | escape_once }} >>> <html> &

Escape_xml

Converts XML entities to their corresponding entity name. If there already is a converted entity name in the text, the & character of that entity name will get converted again. 

{{ "<xsl:template>" | escape_xml }} >>> <xsl:template> 

Escape

Converts HTML entities to their corresponding entity name. If there already is a converted entity name in the text, the & character of that entity name will get converted again. When this is the case, you should use the escape_once filter.

{{ "<html>" | escape }} >>> <html>

Flatten

Flattens the subcollections in a collection so that the collection will have no extra layers.

collection = [ 1, 2, [3, [4, 5]]]
{{ collection | flatten | json }} >>> [ 1, 2, 3, 4, 5]

Find_result_by_key_value

Returns a value from a collection, this value is fetched by a combination of parameters that the filter accepts:

  • The first parameter is the name of a key property in the collection, note that this property has to be unique.
  • The second parameter is the value of that key property for the row that you want to fetch the value of.
  • The third parameter is the name of the property that you want to have returned from the filter.
collection = [{ id: 1, name: "Uno" },{ id: 2, name: "Dos"},{ id: 3, name: "Tres"}]
{{ collection | find_result_by_key_value: "id", "2", "name" }} >>> Dos

First

Gets the first element of the value within the output markup. If the value contains text then it will return the first character of that text, if it contains a collection then it will return the first item of that collection. When using this filter on a collection it is also possible to use the ‘dot’ notation.

collection = ["pear", "apple", "banana", "apple"]
{{ collection | first }} >>> pear
{{ collection.first }} >>> pear

Floor

Rounds a number with decimal down to the nearest number.

{{ 4.6 | floor }} >>> 4

Group

Groups the items of a collection based on a shared property. This filter could, for instance, group a products collection on the product’s related company. The objects of the new collection will contain 2 properties, these properties can be used to fetch the ...:
Key: The key value contains the value that the collection was grouped on. This key should never be changed since it is a reference to the property that was grouped on.
Array: The array value contains the objects of the collection which where grouped on the key value.

products = [{name: "Beef", company: "Beefbaby"},{name: "Banana", company: "FruitsCo"},{name: "Apple", company: "FruitsCo"}]
{% assign products_by_company = products | group: "company" %}
{% for row in products_by_company %}
  {{row.key}}:
  {% for product in row.array %}
    {{ product.name }}
  {% endfor %}
{% endfor %} >>> Beefbaby: Beef Fruitsco: Banana Apple

Image.size

An image property can hold multiple sizes for an image. Add the name of this size to the name of the image property to get the url of this sized image. Read more about image sizes in this article: “Property Reference”.

{{ record.image.size_1 }} >>> Image URL with custom size

Join

Joins the items of a collection together with the set character between the elements. The result will return text.

collection = ["pear", "apple", "banana", "apple"]
{{ collection | join: ", " }} >>> pear, apple, banana, apple

Json

Converts a collection or object into json format.

{{ collection | json }} >>> [{"id":1,"name":"col1"},{"id":2,"name":"col2"}]

Last

Gets the last element of the value within the output markup. If the value contains text then it will return the last character of that text. If it contains a collection, it will return the last item of that collection. When using this filter on a collection it is also possible to use the ‘dot’ notation.

collection = ["pear", "apple", "banana", "apple"]
{{ collection | last }} >>> apple
{{ collection.last }} >>> apple

Localize

Converts a date to the current app locale.

{{ "today" | localize }} >>> 1 may 2019 

Lstrip

Removes all whitespaces from the beginning of a text property.

{{ "             BettyBlocks" | lstrip }} >>> BettyBlocks

Map

Generates a collection based on the values of the given parameter. The parameter is based on the property of the collection used within the output markup.

collection.fruit = ["pear", "apple", "banana", "apple"]
{{ collection | map: 'fruit' }} >>> pearapplebananaapple

Minus

Subtracts the set number value from a number.

{{ 18 | minus: 5 }} >>> 13

Modulo

Divides the set number value by a number and returns the remainder.

{{ 21 | modulo: 5 }} >>> 1 

Newline_to_br

Inserts a <br /> HTML tag in front of each line break of a text property.

text = "Uno
Dos
Tres!" 
{{ text | newline_to_br }} >>> Uno<br /> Dos<br /> Tres!

Plus_days

Adds the set number value as days to a date.

{{ "01-01-2019" | plus_days: 7  | date: '%d-%m-%Y' }} >>> 08-01-2019

Plus

Adds the set number value to a number.

{{ 9 | plus: 10 }} >>> 19

Prepend

Adds the set text before the value within the output markup.

{{ "Blocks" | prepend: "Betty" }} >>> BettyBlocks

Randomize

Gives a collection property randomized sorting.

collection = ["pear", "apple", "banana", "apple"]
{{ collection | randomize }} >>> appleapplebananapear

Raw / No_escape

Converts HTML tags within a text property. HTML tags that are in a text property will not be seen as HTML tags for the page, when using this filter the HTML tags will be properly read.

{{ "<b>This is bold</b>" | raw }} >>> This is bold
{{ "<i>This is italic</i>" | no_escape }} >>> This is italic

Remove_first

Removes the first occurrence of the set text from the value within the output markup.

{{ "BettyBetty" | remove_first: "Betty" }} >>> Betty

Remove

Removes each occurence of the set text from the value within the output markup.

{{ "BettyBlocksBettyBlocks" | remove: "Betty" }} >>> BlocksBlocks

Replace_first

Replaces the first occurrence of the first set text with the second set text from the value within the output markup.

{{ "BlocksBlocks" | replace_first: "Blocks", "Betty" }} >>> BettyBlocks

Replace

Replaces each occurrence of the first set text with the second set text from the value within the output markup.

{{ "BettyBetty" | replace: "Betty", "Blocks" }} >>> BlocksBlocks

Reverse

Reverses the value within the output markup. This only works when this value is a collection property.

collection = ["pear", "apple", "banana", "apple"]
{{ collection | reverse }} >>> apple banana apple pear

Round

Rounds the value within the output markup to the nearest number or number with decimal, depending on the set number.

{{ 3.141592 | round: 2 }} >>> 3.14

Rstrip

Removes all whitespaces from the end of a text property.

{{ "BettyBlocks             " | rstrip }} >>> BettyBlocks

Size

Returns the amount of items in a collection or the amount of characters in a string.

collection = ["pear", "apple", "banana", "apple"]
{{ collection | size }} >>> 4
{{ "BettyBlocks" | size }} >>> 11

Slice

Slices the value within the output markup with the first set number value as offset and the second set number value as length.

{{ "BlocksBettyBlocks" | slice: -11, 11 }} >>> BettyBlocks

Sort

Sorts the elements of a collection based on a property of the item. The order of the sorted collection is case-sensitive.

collection.fruit = ["Pear", "apple", "banana", "Apple"]
{{ collection | sort: 'fruit' | map: 'fruit' }} >>> ApplePearapplebanana

Split

Split a text property on a matching pattern, this matching pattern has to be set as a parameter. The set text value will be used to divide the text property into a collection.

{{ "pear, apple, banana, apple" | split: "," }} >>> ["pear", "apple", "banana", "apple"]

Squeeze

Removes patterns out of a text property based on the set text value. If the set text value occurs multiple times next to each other in the text property then these will be removed out of the text property so that only one occurrence is left.

{{ "BettyBettyBlocks" | squeeze: "Betty" }} >>> BettyBlocks

Strip_html

Removes all HTML tags from a text property.

{{ "<h2>BettyBlocks</h2>" | strip_html }} >>> BettyBLocks

Strip_newlines

Removes all line breaks/newlines from a text property.

text = "Uno
Dos
Tres!" 
{{ text | strip_newlines }} >>> UnoDosTres!

Strip

Removes all whitespaces from both ends of a text property. It does not affect whitespaces between words.

{{ "             Hello World           " | strip }} >>> Hello World

Sum

Adds every value of the set property of a collection together. If the set property contains a number then it will return the total value of those numbers, if it contains text then it will add every value after the other.

collection.fruit = ["Pear", "apple", "banana", "Apple"]
{{ collection | sum: 'fruit' }} >>> PearapplebananaApple

Textilize

Converts certain combinations of characters of a text property into HTML code. For a complete list of all character combinations, you can take a look at this website: “Textile language”.

{{ "*BettyBlocks*" | textilize }} >>> <strong>Bettyblocks</strong>

Time_in_timezone

Changes the value of a Date time property to match the time in another timezone. The time zone can be set by using the timezone’s abbreviation. This only works for Date time properties that are created in the Back Office, not for Date time properties created in liquid.

{{ date | time_in_timezone: "CET" }} >>> 2019-05-03 15:40:51 +0200 

Times

Multiplies the set number value by a number.

{{ 5 | times: 4 }} >>> 20

To_currency

Converts a number or a number with decimal to a currency value. This filter accepts 4 parameters: 

  • The first parameter for the currency unit.
  • The second parameter for the number of decimals.
  • The third parameter for a thousands delimiter.
  • The last parameter for the separator between units. 

If no parameter is used the filter will return in the standard USD notation by default.

{{ 1234567 | to_currency: "€", 2, ".", "," }} >>> €1.234.567,00
{{ 1234567 | to_currency }} >>> $1,234,567.00

Transliterate

Converts all non-ASCII characters of a text property to an ASCII approximation, or if none exists, a question mark character will be used as default.

{{ "à rà skà bing" | transliterate }} >>> A rA skA bing

Truncate_html

Cuts a text property down to a set amount of characters, excluding HTML tags. The amount of characters is the set number value. An ellipsis (...) is added to the text property.

{{ <h1>BettyBlocks</h1> | truncate_html: 5 }} >>> <h1>Blocks</h1>...

Truncate

Cuts a text property down to a set amount of characters. The amount of characters is the set number value. An ellipsis (...) is added to the text property, a second parameter is accepted that will change the ellipsis in the set text value. The chosen text value is also counted in the set amount of characters.

{{ 'BettyBlocks BettyBlocks' | truncate: 12, '!' }} >>> BettyBlocks!

Truncatewords

Cuts a text property down to a set amount of words. The amount of words is the set number value. An ellipsis (...) is added to the text property, a second parameter is accepted that will change the ellipsis in the set text value.

{{ 'BettyBlocks BettyBlocks' | truncatewords: 1, '!' }} >>> BettyBlocks!

Uniq

Removes all double values of a collection property.

collection = ["pear", "apple", "banana", "apple"]
{{ collection | uniq }} >>> pear apple banana

Upcase

Upcases every character of a text property.

{{ "upcase me" | upcase }} >>> UPCASE ME

Url_encode

Converts any URL-unsafe characters in a text property into encoded characters so it can be used in a URL.

{{ "bettyblocks@example.com" | url_encode }} >>> bettyblocks%40example.com

Date format

When using a date expression the format of the date can be set within the expression. Setting up the format is done with special characters. These are the supported special characters:

Years, months and days:

 %Y - Year with century, can be negative, 4 digits at least
 %C - Year / 100, rounded down
 %y - Year % 100 (00..99)
 %m - Month of the year, zero-padded (01..12)
 %_m - Month of the year, blank-padded ( 1..12)
 %B - The full month name ("Januari")
 %^B - The full month name, uppercased ("JANUARI")
 %b - The abbreviated month name ("Jan")
 %^b - The abbreviated month name, uppercased ("JAN")
 %h - Equivalent to %b
 %d - Day of the month, zero-padded (01..31)
 %-d - Day of the month (1..31)
 %e - Day of the month, blank-padded ( 1..31)
 %j - Day of the year, zero-padded (001..366)

Time (Hour, Minute, Second, Subsecond):

 %H - Hour of the day, 24-hour clock, zero-padded (00..23)
 %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
 %I - Hour of the day, 12-hour clock, zero-padded (01..12)
 %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
 %P - Meridian indicator, lowercase ("am" or "pm")
 %p - Meridian indicator, uppercase ("AM" or "PM")
 %M - Minute of the hour (00..59)
 %S - Second of the minute (00..59)
 %L - Millisecond of the second (000..999)
 %N - Fractional seconds digits, default is 9 digits (nanosecond)
 %3N - millisecond (3 digits)
 %6N - microsecond (6 digits)
 %9N - nanosecond (9 digits)

Time zone:

 %z - Time zone as hour and minute offset from UTC (e.g. +0900)
 %:z - Hour and minute offset from UTC with a colon (e.g. +09:00)
 %::z - Hour, minute and second offset from UTC (e.g. +09:00:00)
 %:::z - Hour, minute and second offset from UTC (e.g. +09)

Weekday:

 %A - The full weekday name ("Sunday")
 %^A - The full weekday name, uppercased ("SUNDAY")
 %a - The abbreviated weekday name ("Sun")
 %^a - The abbreviated weekday name, uppercased ("SUN")
 %u - Day of the week, monday is 1 (1..7)
 %w - Day of the week, sunday is 0 (0..6)

ISO 8601 week-based year and week number:

The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
The days in the year before the first week are in the last week of the previous year.

 %G - The week-based year
 %g - The last 2 digits of the week-based year (00..99)
 %V - Week number of the week based year (01..53)

Week number:

The week 1 of YYYY starts with Sunday or Monday (according to %U of %W).
The days in the year before the first week are in week 0.

 %U - Week number of the year, the week starts with Sunday (00..53)
 %W - Week number of the year, the week starts with Monday (0..53)

Seconds since the Unix Epoch:

 %s - Number of seconds since 1970-01-01 00:00:00 UTC.
 %Q - Number of microseconds since 1970-01-01 00:00:00 UTC.

Literal string:

%n - Newline character (\n)
%t - Tab character (\t)
%% - Literal "%" character

Combination:

 %c - Date and time (%a %b %e %T %Y)
 %D - Date (%m/%d/%y)
 %F - The ISO 8601 date format (%Y-%m-%d)
 %v - VMS date (%e-%b-%Y)
 %x - Same as %D
 %X - Same as %T
 %r - 12-hour time (%I:%M:%S %p)
 %R - 24-hour time (%H:%M)
 %T - 24-hour time (%H:%M:%S)
 %+ - Date(1) (%a %b %e %H:%M:%S %Z %Y)

Tags

Tags are used to control all of the logic inside of your application. These tags can be split into 2 types: Block tags and Regular tags. The block tags are tags that require an opening and a closing tag. All the code between these tags is controlled by the logic within the tag. The regular tags don’t have to be closed and all the logic always happens within the tag itself.

Assign

Assigns a value to a variable. An output filter can be combined with this tag to alter the value of the variable.

{% assign var_name = "BettyBlocks" %}

Capture

Captures everything that is in between the tags and assigns the captured value to the given variable. Everything inside of the tags will not be rendered onto the page.

{% capture var_name %}
  "BettyBlocks"
{% endcapture %}

Case

Checks a property or variable on set conditions and executes the first condition that’s true. The case tag is the body of this statement, containing multiple when tags that are used for the conditions. The else tag can be used as a default when no condition matches with the property.

{% assign var = "blocks" %}
{% case var %}
  {% when "betty" %}
    This is betty
  {% when "blocks" %}
    This is blocks
  {% else %}
    This is not betty nor blocks
{% endcase %}

Comment

Any content that is placed in between the tags is turned into a comment, thus making it not visible on the page.

{% comment %} this is a comment {% endcomment %}

Cycle

Cycles through the values set inside the tag each time the tag is called. This tag is usually used within a loop to alternate the values. To have more control over the cycles, a name can be given to the group. This way the cycles can’t be mixed up with each other.

{% cycle "group1": "uno", "dos", "tres" %} #=> uno
{% cycle "group1": "uno", "dos", "tres" %} #=> dos
{% cycle "group2": "uno", "dos", "tres" %} #=> uno
{% cycle "group1": "uno", "dos", "tres" %} #=> tres

For

Loops through a block of code. A for loop can iterate over collections, hashes, and ranges of integers. A loop object is specified to access the objects of the collection that is being looped through. The name for this loop object can be anything but is usually named after the object of the collection.

{% for item in collection %}
  {{ item.name }}
{% endfor %}

Instead of looping over a collection, a range of numbers can also be used to create a loop. Ranges are parentheses containing a start value, two periods, and an end value. The start and end values must be numbers or expressions that resolve to numbers.

{% for item in (1..5) %}
  {{ item }}
{% endfor %} 

To exit a loop early the following tags can be used inside of the loop:
Continue: Immediately ends the current iteration but continues the for loop with the next value.
Break: Immediately ends the current iterations and completely ends the for loop.
Both are best used when combined with an if/else statement. 

{% for item in (1..3) %}
  {% case item %}
    {% when 3 %}
      {% break %}
    {% else %}
      {% continue %}
  {% endcase %}
{% endfor %}

During every for loop special for loop variables can be used to get specific data about the loop or iteration, these variables are called helper variables.

{{ forloop.length }} >>> Length of the entire for loop
{{ forloop.index }} >>> Index of the current iteration
{{ forloop.index0 }} >>> Index of the current iteration (index starts at 0)
{{ forloop.rindex }} >>> Amount of items that are still left
{{ forloop.rindex0 }} >>> Amount of items that are still left (index starts at 0) 
{{ forloop.first }} >>> True when in the first iteration
{{ forloop.last }} >>> True when in the last iteration

To influence which items you receive in your loop and what order they appear in these optional arguments can be added to the for tag:
Limit: Limits the amount of items the for tag loops through.
Offset: Skips over the set number of items.
Reversed: Iterates over the collection from last to first.

{% for item in collection limit:2 offset:4 %}
  {{item}}
{% endfor %}
{% for item in collection reversed %}
  {{item}}
{% endfor %}

A for loop can take an optional else tag to execute some code when there are no items in the collection.

{% for item in collection %}
  {{ item }}
{% else %}
  There are no items!
{% endfor %}

If/Else

With an if/else statement a block of code is executed when a specified condition is true. If the condition is false, another block of code is executed. The specified condition is set inside of the if tag. 

{% if var <= 10 %}
  The condition is true!
{% else %}
  The condition is false!
{% endif %}

A condition is made out of properties and operators, the operators indicate how the properties will be compared to each other. The following operators can be used within the if/else conditions:

== >>> Equal to
!= >>> Not equal to
< >>> Lower than
> >>> Greater than
<= >>> Lower than or equal to
>= >>> Greater than or equal to
contains >>> Contains

It is possible to have multiple conditions within one if tag by using and or or. When using and both of the conditions have to be true for the code block to be executed. When using or either one of the conditions has to be true for the code block to be executed. Another way of having multiple conditions is by using the elsif tag, another condition can be specified within this tag to execute a code block when the condition is true. Any number of elsif tags can be used inside an if tag.

{% if var <= 5 %}
  Var is between 1 and 5
{% elsif var > 5 and var <= 10 %}
  Var is between 6 and 10
{% else %}
  Var is greater than 10
{% endif %}

A condition can also be valid without using an operator. When leaving out the operator and just using a property, the property will be tested for its truthiness. This means that it will return true when the property exists. This works on collections, objects and numbers. Text on the other hand will always return true even when it is empty text. 

Include

Includes another template from the back-end. This is useful for partials or for scripts and stylesheets. The partial name must always be surrounded by quotes.

{% include "template-name" %}

Raw

Temporarily disables tag processing, HTML tags will still be processed but all liquid tags will not. This comes in handy when generating content that uses conflicting syntax.

{% raw %} {{ raw text }} {% endraw %} >>> {{ raw text }}

Unless

The unless tag mirrors the if/else tag, a code block will be executed when a specified condition is false. The condition is set inside of the unless tag. This tag cannot be combined with the elsif and else tags of the if/else tag.

{% unless var == 10 %}
  Var is not 10
{% endunless %}

Url

Returns the URL that belongs to an image.

{{ image.url }} >>> Image URL

In this article