Conditionals
A conditional shows one block of markup or another, depending on a value. Write the test in braces, {if <condition>}, and close the block with {/if}. Add {elseif <condition>} for further tests and {else} for the block that runs when nothing else matched. The same tag works on page templates, reusable blocks, and the built-in system templates.
{if currentUser.isLoggedIn}
<p>Welcome back, {currentUser.firstName}.</p>
{else}
<a href="/login">Sign in</a>
{/if}
Testing presence
Many conditions only ask whether a value exists. Write the token on its own, with no operator:
{if brand.tagline}
<span class="tagline">{brand.tagline}</span>
{/if}
{if brand.media.square_logo}
<img src="{core.project.logo}" alt="{brand.store_name}">
{/if}
A bare token is true when it has a value. These values count as false, so their block is skipped:
| Value | Result |
|---|---|
| A token that resolves to nothing | false |
0 | false |
false, off, null | false |
| An empty list or object | false |
| Any other value | true |
This makes {if} the natural way to give optional values a fallback. Keep the element in place and supply an {else} for the moment before the value is configured. See Variables and tokens for the full fallback pattern.
Negative tests
Put ! in front of a condition to reverse it:
{if !currentUser.isLoggedIn}
<a href="/login">Sign in</a>
{/if}
Comparisons
Use a comparison operator to test an exact value:
| Operator | Meaning | Example |
|---|---|---|
== | Equal to | {if brand.language == "en"} |
!= | Not equal to | {if brand.currency != "USD"} |
> | Greater than | {if brand.tagline.len() > 80} |
< | Less than | {if brand.store_name.len() < 3} |
>= | Greater than or equal to | {if brand.tagline.len() >= 10} |
<= | Less than or equal to | {if brand.store_name.len() <= 40} |
Wrap the value you compare against in single or double quotes; the two styles are equivalent. The == and != operators compare text, ignore letter case, and ignore surrounding spaces, so {if brand.currency == 'USD'} and {if brand.currency == "USD"} behave the same. The greater-than and less-than operators compare numbers.
{if brand.currency == 'USD'}
<span>Prices in US dollars</span>
{elseif brand.currency == 'EUR'}
<span>Prices in euros</span>
{else}
<span>Prices in {brand.currency}</span>
{/if}
{if brand.tagline.len() > 80}
<span>Long tagline</span>
{/if}
A value that resolves to nothing never equals and never differs from anything, so both == and != are false for it. Test presence first, as shown in Testing presence, when a value may be missing.
Combining conditions
Use && when every part must be true and || when at least one part must be true. && binds more tightly than ||, so a || b && c reads as a || (b && c).
{if brand.media.desktop_dark_logo || brand.media.mobile_dark_logo || brand.media.square_logo}
<img src="{core.project.logo}" alt="{brand.store_name}">
{else}
<span>{brand.store_name}</span>
{/if}
{if currentUser.isLoggedIn && !currentUser.is_guest}
<a href="/account">My account</a>
{/if}
Conditions inside loops
A conditional inside an {each} block is evaluated for each item, so you can vary the markup per row:
{each nav_links as=link}
<div class="rounded border p-4">
<strong>{link.label}</strong>
{if link.external}
<span class="text-xs">Opens in a new tab</span>
{elseif link.url == '/account'}
<span class="text-xs">Your account</span>
{else}
<span class="text-xs">Opens in this tab</span>
{/if}
</div>
{/each}
See Loops for the loop syntax.
Nesting
A branch may contain other conditionals. Keep nesting shallow; when a branch grows deep, a separate block or a project variable is usually clearer.
{if currentUser.isLoggedIn}
<div class="card border-indigo-500">
{if currentUser.first_name}
<span>Welcome back, {currentUser.first_name}</span>
{/if}
</div>
{/if}
Reference
| What you want | Write |
|---|---|
| Show a block only when a value is present | {if token}...{/if} |
| Show an alternative when it is not | {if token}...{else}...{/if} |
| Test several values in order | {if a}...{elseif b}...{else}...{/if} |
| Reverse a test | {if !token} |
| Compare text | {if token == "value"} |
| Compare numbers | {if count > 0} |
| Require every condition | {if a && b} |
| Accept any condition | {if a || b} |
Only the operators above are part of condition syntax. Keyword forms such as contains, starts_with, is_empty, and truthy are not recognized in {if}. There is no substring or prefix test; compare the whole value, or use a method where methods are supported. See Methods and formatters.
Reserved tag
{if_skip <condition>}...{/if_skip} is a reserved form that the engine uses while assembling a page. Author templates with {if} and {/if}; the engine rewrites its own markers before the page is served.

