Values and truthiness
#Kinds of values
| Kind | Written as | Notes |
|---|---|---|
| String | "text" or 'text' | A backslash takes the next character literally: "say \"hi\"". There are no escape sequences such as \n. |
| Integer | 42, -7 | Exact 64-bit integers. |
| Decimal | 3.14, -0.5 | 64-bit floating point. Exponent notation is not accepted. |
| Boolean | true, false | |
| Nothing | nil or null | Prints nothing. |
| Empty | empty or blank | Only for comparisons; see Empty. |
| Range | (1..5) | A list of integers; see Loops. |
| Array, map | from data only | There are no array or map literals. |
{{ "double" }} {{ 'single' }} {{ "say \"hi\"" }} {{ 42 }} {{ -0.5 }} {{ true }} [{{ nil }}]double single say "hi" 42 -0.5 true []#Integers stay exact
A number without a decimal point is an exact integer, and arithmetic between two integers stays exact. This matters for large identifiers.
{{ 9007199254740993 | plus: 1 }} {{ 10 | divided_by: 4 }} {{ 10 | divided_by: 5 }}9007199254740994 2.5 2Division keeps a fractional result. A calculation that overflows 64 bits falls back to floating point. Data from the application keeps its own type: numbers decoded from JSON are floating point.
#Truthiness
Conditions such as {% if %} test whether a value is truthy.
| Value | In a condition |
|---|---|
false | false |
nil, a missing field | false |
true | true |
0, 0.0 | true |
"" (empty string) | true |
[], {} (empty array or map) | true |
| any other value | true |
Only false and nothing are false. To ask "is there anything here?", compare with blank, or check .size.
{% if settings.zero %}0 is true{% endif %}, {% if settings.text %}"" is true{% endif %}, {% if settings.missing %}{% else %}missing is false{% endif %}{"settings": {"zero": 0, "text": ""}}0 is true, "" is true, missing is false#Empty and blank
empty and blank are the same marker. A value equals it when the value is nothing, an empty string, or a collection with no entries. A string of spaces is not blank.
{% if settings.title == blank %}No title{% endif %} / {% if settings.tags == empty %}No tags{% endif %} / {% if settings.space == blank %}blank{% else %}not blank{% endif %}{"settings": {"title": "", "tags": [], "space": " "}}No title / No tags / not blank#Comparing values
| Operator | Meaning |
|---|---|
==, != | Equal, not equal. |
<, >, <=, >= | Order. Both sides must be numbers, or both strings. |
contains | Substring of a string, or member of an array. |
Equality is forgiving: numbers compare as numbers, and a string that is a number equals that number. Anything else compares by its printed text.
{{ 1 == 1.0 }} {{ "5" == 5 }} {{ "a" == "a" }} {{ nil == nil }} {{ "1" != 2 }}true true true true trueOrdering is strict. Comparing a number with a string, or anything that is not a number or string, is an error, never a silent false.
{{ 2 > 1 }} {{ "b" > "a" }} {{ 10 >= 10 }}true true true{% if settings.count > "3" %}more{% endif %}{"settings": {"count": 5}}cannot compare number and string with ">"contains looks for a substring in a string, or an equal member in an array. It is always false for maps and other values.
{{ "teapot" contains "tea" }} {{ settings.tags contains "new" }} {{ settings.tags contains "old" }}{"settings": {"tags": ["new", "sale"]}}true true false#How values print
| Value | Prints as |
|---|---|
| String | itself, HTML-escaped |
| Integer | digits: 42 |
| Decimal | shortest exact form: 2.5, 3 for 3.0 |
| Boolean | true or false |
nil | nothing |
| Array | its items printed one after another, with no separator; use join |
| Map | a debugging form; print its fields instead |
{{ settings.list }} | {{ settings.list | join: ", " }} | {{ 3.0 }}{"settings": {"list": ["a", "b", "c"]}}abc | a, b, c | 3Next: Variables, data and scope.