Zephyr Expressions And Operators

Anything inside {curly braces} is evaluated as an expression. Expressions are constructed using a Javascript-like format. Be sure not to include a space immediately following your opening bracket. If you do, your code won't be recognized as Zephyr.

Strings

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?'}
Note: Double quotes are not supported in Email Composer. Use single quotes in Email Composer so your Zephyr renders properly.

Numbers

Integers and floating-point values are both supported.
{3 + 3.0} = 6

Booleans

true and false are reserved words used for boolean math.

Arrays

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

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

Comparisons

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} 

And / Or

&& 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}

Not

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}

Math

Basic math is supported: +-*/, 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}

Modulo

To find the remainder of division of one number by another, use the modulo operator  %.
{if (i % 2) != 0}
  "i am an odd number!"{/if}
Note: Parentheses necessary around the modulo operator when using a comparison. This can be useful for styling content. For instance, creating a two-column table so that any even-numbered item is aligned left, and any odd-numbered item is aligned right:
{foreach content as i,c}
 {if (i % 2) == 0}
 <tr>
 <td align="left"><a href="{c.url}">{c.title}</a></td>
 {else}
 <td align="right"><a href="{c.url}">{c.title}</a></td>
 </tr>
 {/if}
{/foreach}

Parentheses

You can use parentheses to specify the order-of-operations.
{5*3+1} = 16
{5*(3+1)} = 20

Concatenation

The +symbol adds two numbers together, but has other purposes when used for other types:
  • If you use +on strings string1 + string2, it concatenates them (appends string2 to the end of string1)
  • If you use +on lists list1 + list2, it appends the list2to the end of list1
  • If you use +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}

Lambdas

Zephyr supports lambdas (anonymous functions). These are typically used as parameters to functions such as map, filter, or 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.

List Comprehensions

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 mapexpression 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')]}