Zephyr Control Structures

Simple variable replacement is not enough for more complex, personalized templates. Sailthru supports several types of control structures, conditionals, and loops:


Usage: {if expression}result{/if}

You can set up conditional blocks based on a variable.

You can use {if}...{/if}to display something only based on a particular condition.

For if‘s purposes, 0""(empty string), null, and falseall evaluate to false, and anything else evaluates totrue.

{if name} 
<p>Your name is {name}! </p>


Usage: {if expression1}result 1{else if expression2}result 2{else}result 3{/if}

You can add any number of {else} expressions to an {if}.

In this example, result 1 will be the result if expression1 evaluates to true,result 2 will be the result if expression1 evaluates to false but expression2 evaluates to true, and result 3 will be the result if both expression1 and expression2 evaluate to false.

Ternary Operator ? :

Usage: {expression1 ? expression2 : expression3}

Will return expression2 if expression1 evaluates to true, otherwise will return expression3.

Not technically a control structure, but you can use the ternary operator as a handy inline shortcut for if in many situations.

<p>Dear {gender == 'M' ? 'Mr.' : 'Ms.'} {last_name}, </p>

Alternate usage: expression1 ?: expression2

In abbreviated form, it will return expression1 if expression1 evaluates to true; otherwise it will return expression2. This is especially useful if you don’t know if a variable is set or not:

<p>Your current status is: {status ?: 'Unknown'} </p>
You are {is_special_subscriber ? 'definitely' : 'not'} one of our special subscribers.

The template will show the word “definitely” or “not” depending on the value of the is_special_subscriber



If the variable {name} is set to anything, it will get displayed.

<p>Dear {name?:'valued customer'},</p>

If it’s blank or null, the string valued customer

will get inserted instead.

For multiple vars, you would concatenate within the expression: <p>Dear {first + " " + last ?: 'Friend'},</p>   



{switch expression}
{case expression}case{/case}
{case expression}case{/case}
. . .

Given a series of {case}s, picks the first one that matches the value.

{switch gender} 
   {case 'M'}You are a man!{/case} 
   {case 'F'}You are a woman!{/case} 


Usage: {select}{case expression}case{/case}{case expression}case{/case} . . . {/select}

Given a series of {case}s, evaluates them all and picks the one with the highest numeric value. If there is a tie, the tie will go to the earlier {case}.

This is especially useful when combined with Horizon profiling functions like horizon_interest(). You can provide different content based on which of several interests is the strongest.

{case horizon_interest('menswear,fashion')}Check out our new suits!{/case} 
{case horizon_interest('purses')}Try out our new purses{/case} {case horizon_interest('jewelry')}Look at our jewelry selection!{/case} 


Usage: {foreach expression as variable} loop contents {/foreach}

Loop through a list or object, assigning a temporary variable to each item.

<p>Your order is as follows:</p>
  {foreach order as o}

key-value {foreach}

Usage: {foreach expression as keyvar, valuevar} loop contents {/foreach}

You can also loop through both keys and values. If you loop through a list, the key will be the integer index of the item (starting at 0).

  {foreach content as i, c}
    <li>Item #{i+1}: {c.url}</li>

If you pass in an array for one of your variables, you can use a foreach to loop through it. Let’s say you passed in a JSON object for your variables that looked like this:

{"name":"Joe Schmoe", "gender":"male","order":[{"qty":1,"name":"Product A"},{"qty":3,"name":"Product B"}]}

You could loop through the order variable in your template like this:

 {foreach order as o} 

You can also use {break} or {continue} like so:

{filtered_content = []}
{foreach content as c}
    {if !c.url}
    {else if !c.image}
        {push("filtered_content", c)}

Within a loop, you cannot add keys or elements to the iterated object or array. For example, the following code would result in an error:

{obj = { 'a' : 1, 'b' : 2 }}
{foreach obj as k, v}
  {obj.c = 3}

{* comments *}

Enclose Zephyr comments in {* braces with asterisks *}. Unlike HTML comments, Zephyr comments will not render and are not visible to end users.

{* start the main header block here *} 
{include 'header'} 

{* now loop through the content *} 
{foreach content as c} 
{* fill this in later... *} 


Zephyr statements within HTML code comments will still render, so be sure to use the Zephyr commenting syntax as needed according to the description in the {* comments *} section above.