Warning!
This is a legacy document. The features described below are only usable within the classic-generation environment.
Currently, Betty Blocks offers faster and more advanced options that are available in next-gen. Before you start working on some new features in your application, consider doing it using the next-gen version. Good luck!
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
Output markup (which often resolves to text) is surrounded by {{ }}
, matched pairs of curly brackets (ie, braces).
Here is a simple example of Output:
Hello {{name}} (variable)
Hello {{user.name}} (property)
Hello {{ 'tobi' }} (text)
Output markup use filters. Filters are simple methods. They're used to alter or affect the value that has been used as parameter in the tag. Filter are processed in the order they're included in a tag. After processing all tags, the value of the tag is parsed.
Hello {{ 'tobi' | upcase }}
Hello tobi has {{ 'tobi' | size }} letters!
Hello {{ '*tobi*' | textilize | upcase }}
Hello {{ 'now' | date: "%Y %h" }}
Tags
Tag markup (which cannot resolve to text) is surrounded by {% %}
, matched pairs of curly brackets and percentage signs.
tags are used for the programmic logic in your template.
{% for food in menu %}
{{ food.description }}
{% endfor %}
Variables
Variables are instances of values 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.
Examples of filters
Hello {{ name | upcase }} = BETTY
Five times four equals {{ 5 | times: 4 }} = 20
Append
Adds the set text value after the value within the output markup.
{{ 'sales' | append: '.jpg' }} #=> sales.jpg
{{ "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's also possible to convert text to a date property if the correct formatting is used on the text value.
{{ "now" | date: "%a, %b %d, %y" }} >>> Fri, Apr 26, 19
All supported date formats are listed below:
Years, months and days
%Y - Year with century (can be negative, 4 digits at least)
-0001, 0000, 1995, 2009, 14292, etc.
%C - year / 100 (round down. 20 in 2009)
%y - year % 100 (00..99)
%m - Month of the year, zero-padded (01..12)
%_m blank-padded ( 1..12)
%B - The full month name (``January'')
%^B uppercased (``JANUARY'')
%b - The abbreviated month name (``Jan'')
%^b uppercased (``JAN'')
%h - Equivalent to %b
%d - Day of the month, zero-padded (01..31)
%-d no-padded (1..31)
%e - Day of the month, blank-padded ( 1..31)
%j - Day of the year (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)
%12N picosecond (12 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, +09:30, +09:30:30)
Weekday:
%A - The full weekday name (``Sunday'')
%^A uppercased (``SUNDAY'')
%a - The abbreviated name (``Sun'')
%^a 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 a Sunday or Monday (according to %U or %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 (00..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)
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. The optional level argument determines the level of recursion to flatten.
collection = [ 1, 2, [3, [4, 5]]]
{{ collection | flatten }} >>> [ 1, 2, 3, 4, 5]
{{ collection | flatten(1) }} >>> [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 company of the products. 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.
{{ 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
Returns a randomized order of the given collection.
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 }} >>>AEroskobing
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 value.
{{ <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
Url
Returns the URL that belongs to an image.
{{ image.url }} >>> https://assets.bettyblocks.com/asset/123
Tags
Tags are used to control all of the logic inside of your Liquid. 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/when
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 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 %}