What You’ll Learn in This Module
Up to now, your narrations have been linear — they display data and format it, but every customer sees the same text structure. In this module, you’ll learn how to make Cast narrations adaptive — showing different content to different customers based on their data. This is where Liquid transforms from a formatting tool into a personalization engine.
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.
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.
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
The simplest conditional: show something only when a condition is true.
{% if condition %}
Content shown when condition is true.
{% endif %}
Every {% if %} must have a matching {% endif %}. Think of them as matching parentheses.
Real Cast example
{%- assign score = health_score | default: 0 | plus: 0 -%}
{% if score >= 80 %}
Congratulations — your account health is excellent!
{% endif %}
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
When you want one thing for “true” and a different thing for “false”:
{% if condition %}
Content when true.
{% else %}
Content when false.
{% endif %}
Real Cast example
{%- assign score = health_score | default: 0 | plus: 0 -%}
{% if score >= 80 %}
Your account is in great shape!
{% else %}
Let's talk about how we can help strengthen your account.
{% endif %}
Every customer sees one message or the other — never both, never neither.
The if / elsif / else Block
When you need more than two branches — three, four, or more tiers of content:
{% if condition_1 %}
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).
{% endif %}
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
{%- assign score = health_score | default: 0 | plus: 0 -%}
{% if score >= 80 %}
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.
{% endif %}
Three different tones — celebratory, encouraging, and supportive — all from one template.
💡 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.
Comparison Operators
Here are all the operators you can use inside {% if %} conditions:
| Operator | Meaning | Example |
|---|---|---|
== | Equals | {% if tier == "Enterprise" %} |
!= | Not equal | {% if tier != "Starter" %} |
> | Greater than | {% if score > 80 %} |
< | Less than | {% if score < 60 %} |
>= | Greater than or equal | {% if score >= 80 %} |
<= | Less than or equal | {% if score <= 20 %} |
contains | String/array contains value | {% if features contains "Analytics" %} |
The contains operator
contains works on both strings and arrays:
On a string — checks if the substring exists:
{% if contact_email contains "@acme.com" %}
You're emailing from your Acme corporate account.
{% endif %}
On an array — checks if the item is in the list:
{%- assign features = feature_list | split: "," -%}
{% if features contains "Analytics" %}
You have access to Analytics.
{% endif %}
⚠️ contains is case-sensitive. "analytics" does not match "Analytics".
Logic Operators — and / or
You can combine multiple conditions with and (both must be true) or or (either can be true):
{% if score >= 80 and arr_val > 100000 %}
You're a high-performing, high-value account.
{% endif %}
{% if tier == "Enterprise" or tier == "Professional" %}
You have access to advanced reporting.
{% endif %}
⚠️ 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:
{% if a or b and c %}
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.
Real Cast example
{%- assign score = health_score | default: 0 | plus: 0 -%}
{%- assign arr_val = arr | default: 0 | plus: 0 -%}
{% if score >= 80 and arr_val > 100000 %}
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.
{% endif %}
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:
{% if IsEMEA == true %}
{% if IsEMEA %}
✅ Correct — comparing string to string:
{% if IsEMEA == "true" %}
✅ Best practice — use the yes/no pattern:
{%- assign region = IsEMEA | strip -%}
{% if region == "yes" %}
EMEA-specific content.
{% endif %}
This rule applies to every snippet result used in an if condition.
Numeric Comparisons — Always Convert First
The other critical rule: always convert string fields to numbers before using >, <, >=, <=:
❌ Unreliable — string comparison on numeric data:
{% if arr > 50000 %}
✅ Correct — convert, then compare:
{%- assign arr_val = arr | default: 0 | plus: 0 -%}
{% if arr_val > 50000 %}
Nested Conditions
You can put if blocks inside other if blocks for more complex logic:
{%- assign score = health_score | default: 0 | plus: 0 -%}
{%- assign tier = product_tier | default: "" | strip -%}
{% if score >= 80 %}
Your account health is excellent!
{% if tier == "Enterprise" %}
As an Enterprise customer, you also have access to our advanced analytics suite.
{% endif %}
{% else %}
Let's work together to improve your account health.
{% endif %}
💡 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
Use blank to test whether a value is nil or empty before using it:
{% if renewal_date != blank %}
Your contract renews on {{ renewal_date | date: "%B %d, %Y" }}.
{% else %}
We don't have a renewal date on file for your account.
{% endif %}
You can also combine blank checks with other conditions:
{% if csm_name != blank %}
Your CSM, {{ csm_name }}, has prepared this review.
{% else %}
This review has been prepared for you by the Customer Success team.
{% endif %}
Common Mistakes
❌ Forgetting endif:
{% if score >= 80 %}
Great job!
{% else %}
Let's improve.
Missing {% endif %} causes an error.
✅ Every if needs an endif:
{% if score >= 80 %}
Great job!
{% else %}
Let's improve.
{% endif %}
❌ Using = (assignment) instead of == (comparison):
{% if tier = "Enterprise" %}
Single = is for assign, not comparison.
✅ Use double equals for comparison:
{% if tier == "Enterprise" %}
❌ Checking elsif conditions that overlap with earlier ones:
{% if score > 60 %}
Good score.
{% elsif score > 80 %}
Excellent score!
{% endif %}
A score of 85 matches > 60 first and never reaches the > 80 check.
✅ Order from most specific to least specific:
{% if score >= 80 %}
Excellent score!
{% elsif score >= 60 %}
Good score.
{% else %}
Needs improvement.
{% endif %}
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
```liquid {%- assign tier = product_tier | default: "" | strip -%} {% if tier == "Enterprise" %} 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. {% endif %} ``` Key details: - `default: ""` handles nil values - `strip` removes whitespace that might cause comparison failures - The `else` block catches any unexpected tier values (typos, new tiers not yet accounted for) - `cast_pronounce` on "CSM" as a bonus touch for professional audioWhat’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