Zephyr Control Structures

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

{if}

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>{/if}

{if}...{else}...{/if}

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. Another example would be to check if a user has a "first_name" variable on there profile. If so, show it. If not, check if there's a "full_name" variable. If so, pull in the first element (i.e., the user's first name) using the first() function [link]. Otherwise, show a default value:

{if profile.vars.first_name}
Hi, {first_name}!
{else if profile.vars.full_name}
Hi, {first(full_name)}!
{else}
Hi, friend!
{/if}

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 variable.   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. Another example (if you collect a "first_name" custom field on your users and do not wish to have a default salutation to your users): {first_name ? first_name + ", h" : "H"}i there! If the first_name custom field is blank or null, "Hi there!" will display without any default salutation. For multiple vars, you would concatenate within the expression: <p>Dear {first + " " + last ?: 'Friend'},</p>

{switch}

Usage: {switch expression} {case expression}case{/case} {case expression}case{/case} . . . {/switch} Given a series of {case}s, picks the first one that matches the value.

{switch office} 
   {case 'NY'}Thanks for signing up at our New York office!{/case} 
   {case 'LA'}Thanks for checkin in with us in LA!{/case} 
{/switch}

{select}

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.

{select} 
{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} 
{/select} 

{foreach}

Usage: {foreach expression as variable} loop contents {/foreach} Loop through a list or object, assigning a temporary variable to each item, such as items from a Content Feed:

<p>Your stories for today:</p><table> {foreach content as c}
 <tr> <td><a href={c.url}>{c.name}</a></td> </tr> {/foreach}
</table>

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).

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

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 can also use {break} or {continue} within loops. When a {break} statement is evaluated as "true" wihin a loop, the loop will immediately terminate. When a {continue} statement is evaluated as "true" within a loop, the item will be skipped and the loop will move on to the next item. Terminating a loop to pull at the seventh item to limit the number of items populated:

<p>Picked For You:</p>
{foreach content as i,c}
  {if i == 6}
    {break}
  {else}
      <a href="{c.url}">{c.title}</a>
      <br/>
  {/if}
{/foreach}

Skipping over items that do not have a value for an "image" parameter using {continue}:

{foreach content as c}
{if !c.image}
   {continue}
   {else}
   <a href={c.url}>{c.title}</a><br/>
{/if}
{/foreach}
 

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}
{/foreach}

{* 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... *} 
{/foreach}

 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.