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 audio

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

This site uses Just the Docs, a documentation theme for Jekyll.