Module 12: Logic — if / elsif / else
What Is Conditional Logic?
Section titled “What Is Conditional Logic?”Conditional logic lets you say: “If this condition is true, show this content. Otherwise, show something different.” It’s the foundation of all personalized narrations — different health score ranges get different commentary, different product tiers get different feature mentions, different regions get different support information.
{% raw %}> Excel analogy: Conditional logic in Liquid is the equivalent of Excel’s =IF() function. {% if health_score > 80 %}Great!{% else %}Let's improve.{% endif %} works just like =IF(B1>80, "Great!", "Let's improve.") — except each branch can contain entire paragraphs, not just short text.{% endraw %}
Why it matters in Cast
Section titled “Why it matters in Cast”A narration that says the same thing to a customer with a health score of 95 and one with a score of 40 isn’t personalized — it’s just a mail merge. Conditional logic is what turns data insertion into genuine, context-aware communication. One template can express empathy, celebration, urgency, or encouragement depending on the customer’s actual situation.
The if / endif Block
Section titled “The if / endif Block”The simplest conditional: show something only when a condition is true.
{% raw %}
Content shown when condition is true.
{% endraw %}{% raw %}Every {% if %} must have a matching {% endif %}. Think of them as matching parentheses.{% endraw %}
Real Cast example
Section titled “Real Cast example”{% raw %}{%- assign score = health_score | default: 0 | plus: 0 -%}
Congratulations — your account health is excellent!
{% endraw %}If the score is 80 or above, the congratulations message appears. If it’s below 80, nothing is shown — the narration simply skips that section.
The if / else Block
Section titled “The if / else Block”When you want one thing for “true” and a different thing for “false”:
{% raw %}
Content when true.{% else %} Content when false.
{% endraw %}Real Cast example
Section titled “Real Cast example”{% raw %}{%- assign score = health_score | default: 0 | plus: 0 -%}
Your account is in great shape!{% else %} Let's talk about how we can help strengthen your account.
{% endraw %}Every customer sees one message or the other — never both, never neither.
The if / elsif / else Block
Section titled “The if / elsif / else Block”When you need more than two branches — three, four, or more tiers of content:
{% raw %}
Content for condition 1.{% elsif condition_2 %} Content for condition 2.{% elsif condition_3 %} Content for condition 3.{% else %} Fallback content (none of the above).
{% endraw %}Liquid checks each condition from top to bottom and executes the first one that’s true. Once a match is found, the rest are skipped — even if later conditions would also be true.
Real Cast example — three-tier health score
Section titled “Real Cast example — three-tier health score”{% raw %}{%- assign score = health_score | default: 0 | plus: 0 -%}
Your health score of {{ health_score }} puts you in the top tier of our customers. Keep up the great work!{% elsif score >= 60 %} Your health score of {{ health_score }} shows solid engagement with room to grow. Here are some suggestions.{% else %} Your health score of {{ health_score }} tells us there are areas we should focus on together. Let's schedule time to review.
{% endraw %}Three different tones — celebratory, encouraging, and supportive — all from one template.
{% raw %}💡 Notice that we display the original {{ health_score }} string for readability, but we use the converted score variable for the comparisons. This is a common and recommended pattern.{% endraw %}
Comparison Operators
Section titled “Comparison Operators”{% raw %}Here are all the operators you can use inside {% if %} conditions:{% endraw %}
| Operator | Meaning | Example |
|---|---|---|
| {% raw %} | == |
Equals |
| {% raw %} | != |
Not equal |
| {% raw %} | > |
Greater than |
| {% raw %} | < |
Less than |
| {% raw %} | >= |
Greater than or equal |
| {% raw %} | <= |
Less than or equal |
| {% raw %} | contains |
String/array contains value |
The contains operator
Section titled “The contains operator”contains works on both strings and arrays:
On a string — checks if the substring exists:
{% raw %}
You're emailing from your Acme corporate account.
{% endraw %}On an array — checks if the item is in the list:
{% raw %}{%- assign features = feature_list | split: "," -%}
You have access to Analytics.
{% endraw %}⚠️ contains is case-sensitive. "analytics" does not match "Analytics".
Logic Operators — and / or
Section titled “Logic Operators — and / or”You can combine multiple conditions with and (both must be true) or or (either can be true):
{% raw %}
You're a high-performing, high-value account.
You have access to advanced reporting.
{% endraw %}⚠️ Important: Liquid evaluates and/or strictly left to right — there is no operator precedence (no “and before or” rule like in math). If you mix and and or, the results might surprise you:
{% raw %}
{% endraw %}{% raw %}This evaluates as (a or b) and c, not a or (b and c). To be safe, avoid mixing and and or in a single condition. Use separate {% if %} blocks or restructure your logic.{% endraw %}
Real Cast example
Section titled “Real Cast example”{% raw %}{%- assign score = health_score | default: 0 | plus: 0 -%}{%- assign arr_val = arr | default: 0 | plus: 0 -%}
As a top-tier, high-value account, you qualify for our Executive Partnership program.{% elsif score >= 80 %} Your account health is excellent. Let's discuss growth opportunities.{% elsif arr_val > 100000 %} As a high-value account, we want to make sure you're getting the most from the platform.{% else %} We've prepared some recommendations to help strengthen your outcomes.
{% endraw %}String Comparisons — The Snippet Rule
Section titled “String Comparisons — The Snippet Rule”As you learned in Module 2, snippets return strings. This means snippet output must be compared as a string, not a boolean:
❌ Unreliable — comparing string to boolean:
{% raw %}
{% endraw %}✅ Correct — comparing string to string:
{% raw %}
{% endraw %}✅ Best practice — use the yes/no pattern:
{% raw %}{%- assign region = IsEMEA | strip -%}
EMEA-specific content.
{% endraw %}This rule applies to every snippet result used in an if condition.
Numeric Comparisons — Always Convert First
Section titled “Numeric Comparisons — Always Convert First”The other critical rule: always convert string fields to numbers before using >, <, >=, <=:
❌ Unreliable — string comparison on numeric data:
{% raw %}
{% endraw %}✅ Correct — convert, then compare:
{% raw %}{%- assign arr_val = arr | default: 0 | plus: 0 -%}
{% endraw %}Nested Conditions
Section titled “Nested Conditions”You can put if blocks inside other if blocks for more complex logic:
{% raw %}{%- assign score = health_score | default: 0 | plus: 0 -%}{%- assign tier = product_tier | default: "" | strip -%}
Your account health is excellent!
As an Enterprise customer, you also have access to our advanced analytics suite.
{% else %} Let's work together to improve your account health.
{% endraw %}💡 Keep nesting shallow. One level of nesting is fine; two levels gets hard to read; three or more should be restructured. Use elsif or separate the logic into snippets instead of deeply nesting.
Checking for Blank Values in Conditions
Section titled “Checking for Blank Values in Conditions”Use blank to test whether a value is nil or empty before using it:
{% raw %}
Your contract renews on {{ renewal_date | date: "%B %d, %Y" }}.{% else %} We don't have a renewal date on file for your account.
{% endraw %}You can also combine blank checks with other conditions:
{% raw %}
Your CSM, {{ csm_name }}, has prepared this review.{% else %} This review has been prepared for you by the Customer Success team.
{% endraw %}Common Mistakes
Section titled “Common Mistakes”❌ Forgetting endif:
{% raw %}
Great job!{% else %} Let's improve.{% endraw %}{% raw %}Missing {% endif %} causes an error.{% endraw %}
✅ Every if needs an endif:
{% raw %}
Great job!{% else %} Let's improve.
{% endraw %}❌ Using = (assignment) instead of == (comparison):
{% raw %}
{% endraw %}Single = is for assign, not comparison.
✅ Use double equals for comparison:
{% raw %}
{% endraw %}❌ Checking elsif conditions that overlap with earlier ones:
{% raw %}
Good score.{% elsif score > 80 %} Excellent score!
{% endraw %}A score of 85 matches > 60 first and never reaches the > 80 check.
✅ Order from most specific to least specific:
{% raw %}
Excellent score!{% elsif score >= 60 %} Good score.{% else %} Needs improvement.
{% endraw %}Try It Yourself
Section titled “Try It Yourself”Exercise: Write a conditional block that handles four scenarios based on product_tier (a string from CRM):
- “Enterprise” → “You have access to all features including advanced analytics.”
- “Professional” → “You have access to core features and standard reporting.”
- “Starter” → “You have access to essential features. Talk to your CSM about upgrading.”
- Any other value → “Contact your CSM to explore available plans.”
Include proper default and strip handling.
Click to reveal the answer
{% raw %}{%- assign tier = product_tier | default: "" | strip -%}
You have access to all features including advanced analytics.{% elsif tier == "Professional" %} You have access to core features and standard reporting.{% elsif tier == "Starter" %} You have access to essential features. Talk to your {{ "CSM" | cast_pronounce }} about upgrading.{% else %} Contact your {{ "CSM" | cast_pronounce }} to explore available plans.
{% endraw %}Key details:
default: ""handles nil valuesstripremoves whitespace that might cause comparison failures- The
elseblock catches any unexpected tier values (typos, new tiers not yet accounted for) cast_pronounceon “CSM” as a bonus touch for professional audio
What’s Next
Section titled “What’s Next”In Module 13, you’ll learn two more logic structures: unless (the inverse of if) and case/when (a cleaner way to handle multiple specific values).
📖 Official documentation:
- Tags/Blocks: https://school.cast.app/liquid/liquid-blocks.html