# Directives

### Operators

These operators are used inside if statments and other ESL when making comparisons.

| Operator                      | Description                                                                           | Example                                                                                                                    |
| ----------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| <p>eq<br>neq</p>              | <p>Is equal to<br>Is not equal to</p>                                                 | <p>{{ If (\[Merge] eq "Value") }}<br>{{ If (\[Merge] neq "Value") }}</p>                                                   |
| <p>gt<br>lt<br>gte<br>lte</p> | <p>Greater than<br>Less than<br>Greater than or equal to<br>Less than or equal to</p> | <p>{{ If (\[Merge] gt 5) }}<br>{{ If (\[Merge] lt 5) }}<br>{{ If (\[Merge] gte 5) }}<br>{{ If (\[Merge] lte 5) }}</p>      |
| <p>in<br>notin</p>            | <p>Is in the list of supplied values<br>Is not in the list of supplied values</p>     | <p>{{ If (\[Merge] in "Value 1", "Value 2", "Value 3") }}<br>{{ If (\[Merge] notin "Value 1", "Value 2", "Value 3") }}</p> |
| all                           | If the test value matches all of the list of values                                   | {{ If ("Value" all \[Merge 1], \[Merge 2], \[Merge 3]) }}                                                                  |

***

### If

The if statement is used to show/hide certain information for a person depending on the value of field. This allows one person to see one thing, but another to see something completely different.

**Basic structure**

If statements always follow this basic structure:

```
{{ If( conditional statement goes here ) }} 
    Show this text 
{{ Else }}
    Otherwise show this text
{{ EndIf }}
```

The {{Else}} section is optional:

```
{{ If( conditional statement goes here ) }}
    Show this text 
{{ EndIf }}
```

Note that if statements can only have two possible outcomes, i.e. a contact either matches the if condition, or they fall into the else group. You can nest if statements if you need to create more complex logic, or you can use a [switch](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/directives#switch).

**Conditional statements**

The conditional statements usually contain three parts:

* Left half you're comparing - often a merge field, but can be a static value
* An [operator](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/directives#operators) - e.g. eq, neq
* Right half you're comparing - often a static value, but can be a merge field

Remember that [data types](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/data-types) matter here, for example if your static value is a [string](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/data-types#string) then it will need to be wrapped in quotes.

You can see a few samples of different conditional statements below.

* If a yes/no field is true (i.e. yes):

```
{{ If([Merge] eq True) }}
```

* If a field is equal to a specific value:

```
{{ If([Merge] eq "Value") }}
```

* If a field is not empty:

```
{{ If([Merge] neq null) }}
```

* If a value is in the output from a list of merge fields:

```
{{ If("Value" in [Merge 1], [Merge 2], [Merge 3]) }}
```

* If a field value exists in a list of values:

```
{{ If([Merge] in "Value 1", "Value 2", "Value 3") }}
```

**Examples**

Show different content if city from database is Auckland:

```
{{ If([Database.City] eq "Auckland") }}
   Check out these awesome shows coming up in Auckland this month!
{{ Else }}
   Find out what's going on around NZ this month.
{{ EndIf }}
```

Show different content if the contact doesn't have a first name in the database (note you could also do this with [coalesce](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/directives#coalesce)):

```
{{ If([Database.First Name] neq null) }}
   Hi [Database.First Name]
{{ Else }}
   Hi there
{{ EndIf }}
```

Show different content based on if a person's favourite fruit is in a list:

```
{{ If([Database.Favourite Fruit] in "Pineapple", "Passionfruit", "Mango") }}
   As a tropical fruit lover, we think you'd love our new tropical fruit juice.
{{ Else }}
   Why not try something new? You may find our tropical fruit juice is worth a try.
{{ EndIf }}
```

Show different content if city from database is Auckland, and if they live in the central city (nested if statements):

```
{{ If([Database.City] eq "Auckland") }}
    {{ If([Database.Suburb] eq "Central City") }}
        Check out these awesome shows coming up in Auckland central this month! 
    {{ Else }}       
        Check out these awesome shows coming up in the Auckland region this month!
    {{ EndIf }}
{{ Else }}
   Find out what's going on around NZ this month. 
{{ EndIf }}
```

***

### Switch

While an if statement can only ever have two outcomes (the contact either matches the condition or they don't) the switch allows you to have infinite different outcomes.

There are two ways to use a switch:

1. Provide a merge field and show a different result based on the value each contact has in that field
2. Provide individual conditional statements for each case

You can include as many cases as needed and can provide an optional default fallback for if none of the other cases are a match.

**Providing a merge field**

When providing a merge field the merge field is inserted at the top in the switch and each case simply contains the database value you want to show the content for.

```
{{ Switch([Merge]) }}

    {{ Case("Value 1") }}
        Text for Value 1
    {{ EndCase }}
	
    {{ Case("Value 2") }}
        Text for Value 2
    {{ EndCase }}

    {{ Case("Value 3") }}
        Text for Value 3
    {{ EndCase }}
	
    {{ Default }} 
        Text if contact doesn't match any of the other cases
    {{ EndDefault }}

{{ EndSwitch }}
```

**Provide individual conditional statements**

When providing individual conditional statements the switch is empty, and the conditional statements go against each case. This allows you to use more complex logic around when different cases are shown. They can even use different merge fields.

Note that if a contact matches multiple cases only the first one will be displayed.

```
{{ Switch }}

    {{ Case( conditional statement goes here ) }}
        Text if contact matches condition
    {{ EndCase }}

    {{ Case( conditional statement goes here ) }}
        Text if contact matches condition
    {{ EndCase }}

    {{ Default }}
        Text if contact doesn't match any of the other cases
    {{ EndDefault }}

{{ EndSwitch }}
```

**Examples**

Change out different messages based on what city a person has in their database field. If the value in their database field isn't "Auckland", "Wellington" or "Christchurch" then they will see the default case.

```
{{ Switch([Database.City]) }}

    {{ Case("Auckland") }}
        With the rain in Auckland today it's a great opportunity to check out these indoor activities.
    {{ EndCase }}
	
    {{ Case("Wellington") }}
        What a stunning day in Wellington, perfect weather for doing some swimming.
    {{ EndCase }}

    {{ Case("Christchurch") }}
        A little nippy in Christchurch today, dress up warm to see the fireworks tonight.
    {{ EndCase }}
	
    {{ Default }} 
        The last month of summer is here so make sure you make the most of it.
    {{ EndDefault }}

{{ EndSwitch }}
```

Use individual conditional statements to show different messages based on age. Using conditional statements in this case allows you to use greater than and less than [operators ](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/directives#operators)so only three cases are needed. If simply providing a merge field you'd need to have a separate case for every possible age.

```
{{ Switch }}

    {{ Case([Database.Age] lt 17) }}
        Sorry, this concert is only available to those over the age of 18.
    {{ EndCase }}

    {{ Case([Database.Age] eq 17) }}
        So close but you're not quite old enough. We look forward to seeing you next year!
    {{ EndCase }}

    {{ Case([Database.Age gte 17]) }}
        Are you ready to book your tickets?
    {{ EndCase }}

{{ EndSwitch }}
```

***

### Coalesce

Coalesce is used to display only one non-blank value from a list of merge fields for a contact. Engage will look at the value of each merge field in the list one at a time in the order supplied until if finds one that has a value (i.e. is not null/blank), then it will output that value.

You can include as many merge fields as you want, and can optionally include a static value at the end to be displayed if all the merge fields are blank.

```
{{ Coalesce([Merge 1], [Merge 2], "Default") }}
```

**Example**

Show a persons first name if you have it, if it's blank then show their salutation, and if that's blank too then just show "there":

```
Hi {{ Coalesce([Database.First Name], [Database.Salutation], "there") }}
```

***

### Reverse Coalesce

Reverse coalese will output all values but only if all merge fields have a value (i.e. are not null/blank). If a single merge field is blank then nothing will be output. This is often useful for including conjunctions (e.g. "and") in a sentence but only when you actually have two values to join.

You can include as many merge fields and static values as you want, in the order you want them to be output.<br>

```
{{ RCoalesce([Merge 1], [Merge 2], "Default") }}
```

**Example**

In this example if customer 2 name is blank then only "Hi Customer 1 Name" will be output, however if there is a customer 2 name then it say "Hi Customer 1 Name and Customer 2 Name". Note the space at the end of the "and" which is included in the brackets.

```
Hi [Database.Customer 1 Name] {{ RCoalesce("and ", [Database.Customer 2 Name]) }}
```

***

### Literal

Sometimes you want to use square brackets "\[]" or double curly braces "{{}}" for something other than ESL. If you try to do that normally however Engage will think that what you've entered should be a merge field and you will get an eror saying that the value could not be found.<br>

This is where the {{ Literal }} statement comes in. Engage will leave alone any square brackets or double curly braces inside literal tags. This also means that any ESL you include inside literal tags will be ignored - so be careful where you use it.

```
{{ Literal }}
    You can use square brackets [] and double curly braces {{}} in here and they will be ignored
{{ EndLiteral }}
```

**Example**

Ignore the CSS selector in style sheets (often selectors with square brackets are used in mobile styles):

```
{{ Literal }}
    <style type="text/css">td[class=border] { border:1px solid #000000; }</style>
{{ EndLiteral }}
```

***

### Cast

If you have data in a field that isn't the correct field type, such as a number in a text field, then you can use cast to tell ESL to treat the field as a different field type. This allows you to make use of field type [formatters ](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/format-merge-fields)to change the way your field outputs.

```
{{ Cast([Merge] as "Type") }}
    [Value(g)]
{{ EndCast }}
```

Between the open and end cast tags you will have access to a \[Value] merge field that Engage will treat as the appropriate data type and on which the required formatter can be used.

Available data types are:

* MobileNumber
* WholeNumber
* Decimal
* Date
* Time
* YesNo
* Text
* UniqueIdentifier

There is also a [cast function](https://resources.ubiquity.co.nz/home/using-engage/engage-scripting-language/functions#cast) that is useful when stringing multiple functions together to perform a sequence of actions on the value before it is output (e.g. cast it as a date, add 1 month to that value, then output the result).

**Example**

In the example below there is a database field called "Purchase Price" but it was accidentally set up as a text field type instead of a decimal field. In order to format this field to output as a currency with a $ and two decimal places, we need to cast this field as a decimal. Now we can merge out the \[Value] formatted with a (c) for currency.

```
{{ Cast([Database.Purchase Price] as "Decimal") }}
    [Value(c)]
{{ EndCast }}
```

***

### Split

The split directive allows you to split a string of text into multiple parts by defining the character you would like to split on. You can then loop over the resulting items and format them as required.

The most basic syntax is:

```
{{ Split([Merge] on ";") }}
    {{ Item }}
        [Item]
    {{ EndItem }}
{{ EndSplit }}
```

However, there are additonal sections you can include that give you more control over the output:

```
{{ Split([Merge] on ";") }}
    {{ Header }}
        This is only output once at the start, but only if there is at least one item to output
    {{ EndHeader }}
    {{ Item }}
        This is where each [Item] is output, the [ItemIndex] will output the index of the current item
    {{ EndItem }}
    {{ Alternate }}
        You can use this to display every second [Item] in a different way, [ItemIndex] can be used here too
    {{ EndAlternate }}
    {{ Separator }}
        This is output between items
    {{ EndSeparator }}
    {{ Footer }}
        This is only output once at the end, but only if there is at least one item to output
    {{ EndFooter }}
{{ EndSplit }}
```

The character can be whatever you like, for example you could break a sentence down into it's individual words by splitting on a space " ". &#x20;

The \[Item] merge field is where Engage will insert the output for each item in the split. \[ItemIndex] will output a count (starting at 1) for the item currently being output.

Engage will look over the data from the merge field supplied and split it on the chosen character. If there is at least one item to output it will: include the header, then jump back and forth between inserting items and alternate items with a separator in between until it runs out, then output the footer.

**Example**

If you have a checkbox list on an Engage form this will be inserted into the database as a semi-colon separated list, e.g. "Chocolate; Lollies; Cake". Say however that when a person fills in this form that you want to send them a bullet list of their selected options. You could do the following:

```
{{ Split([Merge] on ";") }}
    {{ Header }}
        <ul>
    {{ EndHeader }}
    {{ Item }}
        <li>[Item]</li>
    {{ EndItem }}
    {{ Footer }}
        </ul>
    {{ EndFooter }}
{{ EndSplit }}
```

Including the \<ul> and \</ul> in the header and footer respectively allows you to only include those tags when there is at least one item to output, i.e. when the person ticked at least one box on the form.

***

### While

The while directive allows you to loop until a condition matches, at which point it will stop looping.

The most basic syntax is:

```
{{ While( condition goes here ) }}
    {{ Item }}
        Output this
    {{ EndItem }}
 {{ EndWhile }}
```

This also has access to additional sections however:

```
{{ While( condition goes here ) }}
    {{ Header }}
        This is only output once at the start, but only if there is at least one item to output
    {{ EndHeader }}
    {{ Item }}
        This is output, usually you'd also increment a value for your condition here too
        [ItemIndex] can be merged and will output the index of the current item
    {{ EndItem }}
    {{ Alternate }}
        This is output for every second item, usually you'd also increment a value for your condition here too
        [ItemIndex] can be merged and will output the index of the current item
    {{ EndAlternate }}
    {{ Separator }}
        This is output between items
    {{ EndSeparator }}
    {{ Footer }}
        This is only output once at the end, but only if there is at least one item to output
    {{ EndFooter }}
{{ EndWhile }}
```

\[ItemIndex] will output a count (starting at 1) for the item currently being output.

If your condition is never matched (i.e. it gets stuck in an infinite loop) then Engage will not output anything.

**Example**

This will output five paragraphs, each numbered in series, e.g. "This is item 2":

```
{{ While([@var] neq 5) }}
    {{ Item }}
        <p>This is item [ItemIndex]</p>
        {{ Increment(@var, 1) }}
    {{ EndItem }}
 {{ EndWhile }}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ubiquity.co.nz/documentation/keep-learning/esl-ubiquitys-scripting-language/directives.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
