Anything inside {curly braces} is evaluated as an expression. Expressions are in a Javascript-like format.
Use either single-quotes or double-quotes to denote strings, as you prefer. The backslash is used to escape quotes.
{"apples"} is the same as {'apples'}
{'What\'s up?'}
Integers and floating-point values are both supported.
{3 + 3.0} = 6
true and false are reserved words used for boolean math.
You can define arrays inline, or pass them in as variables. They are defined using JSON syntax and indexed starting at 0.
{set('myvar', [1,2,"three"])}
{myvar[2]} equals three
Objects are also defined using JSON syntax. You can access objects using dot notation or array index notation.
{set('myvar',{"attrib1":"value1","attrib2":"value2"})}
{myvar.attrib2} equals value2
{myvar['attrib2']} equals value2
Standard comparison operators are supported: ==, !=, >=, >, ⇐, <
{if 2 == 2.0}this will display{/if}
{if 2 <= 2}so will this{/if}
{if 2 < 2}but this won't{/if}
&& functions as a boolean and, while || functions as a boolean or.
{if true && false}
this will not display
{/if}
{if true || false}
but this will
{/if}
You can use the ! as a not-operator. This is especially handy when checking whether a variable has been set.
{if !true}This won't display{/if}
{if !source}
Hey {name}, we don't know where you came from!
{/if}
Basic math is supported: +, -, *, /, and % (the modulo operator)
Useful, among other situations, when applying multipliers to Horizon interests.
{if horizon_interest('apples')*2 >= horizon_interest('oranges')}
You're at least half as interested in apples as you are in oranges!
{/if}
You can use parentheses for order-of-operations.
{5*3+1} = 16
{5*(3+1)} = 20
The + symbol adds two numbers together, but has other purposes when used for other types:
+ on strings string1 + string2, it concatenates them (appends string2 to the end of string1)+ on lists list1 + list2, it appends the list2 to the end of list1+ on objects object1 + object2, it merges them (returns object1 with all of object2's keys copied onto it)
{'Zehpyr' + ' is fun'} = Zephyr is fun
{[1, 2, 3] + [4, 5, 6]} = [1, 2, 3, 4, 5, 6]
{{'a':1,'b':2} + {'b':3,'c':4}} = {'a':1,'b':3,'c':4}
Zephyr supports lambdas (anonymous functions). These are typically used as parameters to functions such as map, filter and sort.
The lambda syntax is similar to Python:
lambda x: x*2
lambda x,y: (x != y)
For more specific examples on how to use lambdas, see the documentation on the functions above.
Zephyr supports Python-style list comprehensions. This is a concise, elegant way to apply a map or filter to a list.
The format is:
[map for varname in list]
or
[map for varname in list if condition]
The map expression is applied to each member of the list that matches condition. This is probably easier illustrated with some examples:
applying a map function:
{[x*2 for x in [1, 2, 3, 4, 5]]} = [2, 4, 6, 8, 10]
applying a filter:
{[x for x in [1, 2, 3, 4, 5] if x > 2]} = [3, 4, 5]
applying both:
{[x*2 for x in [1, 2, 3, 4, 5] if x > 2]} = [6, 8, 10]
This is especially useful for filtering content pulled from a data feed. For example, to filter for the stories tagged football in a list called content pulled from your data feed, you could do:
{content = [c for c in content if contains(c.tags, 'football')]}