What You’ll Learn in This Module

By the end of this module, you will understand what Liquid is, where it came from, how Cast.app uses it, and — most importantly — why it matters for your day-to-day work in Customer Success and Revenue Operations. No programming experience is required. If you’ve ever used mail merge in Word or written an IF formula in Excel, you already have the mental model you need.


What Is a Templating Language?

Before we talk about Liquid specifically, let’s talk about the problem it solves.

Imagine you need to send a personalized quarterly business review (QBR) to 500 customers. Each review should greet the contact by name, show their company’s health score, mention their renewal date, and adjust the tone based on how the account is performing. You could write 500 versions by hand — or you could write one version with placeholders that get filled in automatically with each customer’s data.

Analogy: Think of mail merge in Microsoft Word. You write a single letter template with fields like «First_Name» and «Company», connect it to a spreadsheet, and Word produces a personalized letter for every row. A templating language does exactly the same thing — but with more power. It can also make decisions (“if the health score is above 80, say congratulations; otherwise, suggest a meeting”) and loop through lists (“here are your top 3 features this quarter”).

A templating language is the set of rules for writing those placeholders and that logic. Liquid is one such language — and it’s the one Cast.app uses.


Why Does This Matter in Cast?

Cast.app creates personalized, narrated presentations for your customers at scale. Every slide, every sentence the narrator speaks, and every data point shown on screen can be tailored to an individual contact using Liquid. When you write Liquid inside a Cast narration, you’re telling Cast: “When you generate this presentation for Customer X, pull in their data and make their version of this content.”

Without Liquid, every Cast presentation would say the same thing to every customer. With Liquid, one template becomes thousands of unique, relevant experiences.


A Brief History of Liquid

Liquid was created in 2006 by Tobias Lütke, the co-founder of Shopify. He needed a templating language that was safe — meaning that users (Shopify store owners) could customize their online stores without accidentally breaking anything or accessing things they shouldn’t. Liquid was designed to be simple enough for non-programmers while powerful enough to handle real business logic.

Since then, Liquid has become one of the most widely used templating languages in the world. If you’ve ever customized a Shopify store theme, you’ve already used Liquid — even if you didn’t know it by name.

The original Liquid is written in Ruby (the programming language Shopify uses). Over the years, other developers have re-created Liquid in other programming languages so it can be used outside of Shopify. One of those recreations is python-liquid, an open-source Python implementation written by James Prior. This is the version Cast.app uses.

Here’s the family tree:


Shopify Liquid (Ruby, the original — shopify.github.io/liquid)
  ↓  specification and syntax
python-liquid (Python open-source port — by James Prior)
  ↓  base engine
Cast.app custom environment
  ↓  adds cast_* filters + company_titlecase module
What you write in Cast narrations

What this means for you:

  • The core syntax you’ll learn — placeholders like {{ }}, logic blocks like {% %}, and filters — follows the Shopify Liquid specification. This means any Shopify Liquid tutorial or reference you find online covers the fundamentals accurately.
  • Cast adds five custom filters on top of the standard set (cast_titlecase, cast_apostrophe, cast_pronounce, cast_highlight, cast_footnote) that are designed specifically for customer success personalization.
  • Cast runs in strict mode, which we’ll explain next.

Think of it this way: Cast Liquid is standard Liquid with a few extra tools added specifically for CS personalization, running in a stricter mode that catches your mistakes early instead of letting them slip through silently.


Strict Mode — Cast’s Safety Net

In standard Shopify Liquid, if you reference a variable that doesn’t exist — say you type {{ contct_first_name }} with a typo — the system silently outputs nothing. Your presentation would just have a blank space where the name should be, and you might not notice until a customer sees it.

Cast runs Liquid in strict mode. This means if a variable doesn’t exist or is empty, Cast raises an error immediately. This catches typos, missing data fields, and other mistakes before your presentation reaches a customer.

Excel analogy: Strict mode is like Excel showing #REF! when a formula references a cell that doesn’t exist, rather than silently showing a blank cell. It’s initially a bit more demanding, but it saves you from embarrassing mistakes in production.

The practical consequence: you should always provide a fallback value for any field that might be missing. Liquid has a built-in tool for this called the default filter:


{{ contact_first_name | default: "there" }}

This says: “Show the contact’s first name. But if that field is empty or missing, show the word ‘there’ instead.” So the narration would say either “Hi Jason,” or “Hi there,” — never “Hi ,” with an awkward blank.

You’ll learn all about default and other filters in later modules. For now, just remember: Cast’s strict mode is your friend. It’s picky so your customers don’t see broken content.


The Three Building Blocks of Liquid

Every piece of Liquid you’ll ever write in Cast uses one or more of just three building blocks. That’s it — three. Let’s meet them.

1. Output — Displaying a Value

When you want to show a piece of data, you wrap it in double curly braces:


{{ contact_account_name }}

Mail merge analogy: This is identical to «Company» in a Word mail merge. It’s a placeholder that gets replaced with real data when the presentation is generated.

Real Cast example:

If the contact’s account name in Salesforce is “ACME CORP”, then:


Welcome to {{ contact_account_name }}'s quarterly review.

produces:


Welcome to ACME CORP's quarterly review.

(We’ll fix that ALL CAPS problem in Module 8 when you learn cast_titlecase.)

2. Filters — Transforming a Value

A filter modifies a value before it’s displayed. You apply a filter using the pipe character (|), and you can chain multiple filters together, one after another.


{{ contact_account_name | upcase }}
{{ contact_account_name | cast_titlecase | cast_apostrophe }}

Excel analogy: Filters are like Excel functions wrapped around a cell reference. {{ contact_account_name | upcase }} is the Liquid equivalent of =UPPER(A1) in Excel. Chaining filters — {{ name | cast_titlecase | cast_apostrophe }} — is like nesting functions: =APOSTROPHE(TITLECASE(A1)).

Real Cast example:


{{ contact_account_name | cast_titlecase | cast_apostrophe }} health score has improved.

If the account name is “ACME LLC”, this produces:


Acme LLC's health score has improved.

The cast_titlecase filter fixed the casing, and cast_apostrophe added the possessive.

3. Tags — Adding Logic

Tags let you make decisions and repeat actions. They’re wrapped in {% %} (curly brace + percent sign).


{% if health_score > 80 %}
  Your account is in great shape!
{% else %}
  Let's talk about how we can help.
{% endif %}

Excel analogy: This is Liquid’s version of the =IF() function. {% if health_score > 80 %} is like =IF(B1>80, "Great shape!", "Let's talk.") — except in Liquid, each branch can contain entire paragraphs, formatted text, or even more logic.

Real Cast example:


{% assign score = health_score | plus: 0 %}
{% if score >= 80 %}
  {{ contact_first_name }}, your health score of {{ health_score }} puts you among our top-performing accounts.
{% elsif score >= 60 %}
  {{ contact_first_name }}, your health score of {{ health_score }} shows solid engagement with room to grow.
{% else %}
  {{ contact_first_name }}, your health score of {{ health_score }} tells us there are areas we should focus on together.
{% endif %}

Don’t worry about the {% assign score = health_score | plus: 0 %} line for now — that’s converting the health score from text to a number so the comparison works correctly. You’ll learn exactly why and how in Module 5.


Putting It All Together — A Taste of Real Cast Liquid

Here’s a realistic Cast narration opening that uses all three building blocks. Read through it and see how much you can already follow:


Hi {{ contact_first_name | default: "there" }},

Welcome to {{ contact_account_name | cast_titlecase | cast_apostrophe }}
Executive Business Review.

{% assign score = health_score | plus: 0 %}
{% if score >= 80 %}
  Your account health is strong, and we're excited to share your results.
{% elsif score >= 60 %}
  Your account is performing well, with some opportunities to explore.
{% else %}
  We've prepared some recommendations to help strengthen your outcomes.
{% endif %}

Your contract renews on {{ renewal_date | date: "%B %d, %Y" }}.

For a contact named Jason at ACME LLC with a health score of 85 and a renewal date of 2026-09-15, this generates:


Hi Jason,

Welcome to Acme LLC's Executive Business Review.

Your account health is strong, and we're excited to share your results.

Your contract renews on September 15, 2026.

For a different contact — Priya at GLOBEX INC with a health score of 55 and a renewal date of 2026-04-01:


Hi Priya,

Welcome to Globex Inc's Executive Business Review.

We've prepared some recommendations to help strengthen your outcomes.

Your contract renews on April 01, 2026.

One template. Thousands of unique presentations. That’s the power of Liquid in Cast.


What You Won’t Need to Learn

If you’ve seen programming tutorials before, you might be bracing for talk of databases, APIs, deployment, or debugging in a terminal. None of that applies here.

In Cast, you write Liquid directly inside the narration editor — the same place you write your presentation text. There’s no separate coding environment. There’s no compiling or deploying. You write Liquid, preview the output with real data, and publish. That’s the whole workflow.

You also don’t need to worry about Liquid doing anything dangerous. Liquid was specifically designed to be safe — it can’t delete files, send emails, access the internet, or do anything beyond formatting and displaying the data you give it.


Common Mistakes — Even in This Early Stage

Before you’ve written a single line of Liquid, here are three mistakes that trip up new users immediately:

Confusing {{ }} with {% %}:


{% contact_first_name %}

This tries to run the name as a logic command, not display it. Liquid won’t know what to do.

Use double curly braces to display values:


{{ contact_first_name }}


Forgetting a fallback in strict mode:


{{ contact_first_name }}

If contact_first_name is empty or missing in the data, Cast’s strict mode will raise an error.

Always add a default for fields that might be missing:


{{ contact_first_name | default: "there" }}


Forgetting endif to close an if block:


{% if score > 80 %}
  Great job!

Every if needs a matching endif:


{% if score > 80 %}
  Great job!
{% endif %}

💡 Think of {% if %} and {% endif %} as matching parentheses — every opening one needs a closing one.


Try It Yourself

Exercise: Without looking back, identify the three building blocks of Liquid and match each to its syntax:

Building Block Syntax
??? {{ }}
??? {{ value \| filter }}
??? {% %}

Write a single line of Liquid that displays the contact’s first name, converted to uppercase, with a fallback of “Valued Customer” if the name is missing.


Click to reveal the answer **The three building blocks:** | Building Block | Syntax | |---|---| | Output | `{{ }}` | | Filters | `{{ value \| filter }}` | | Tags | `{% %}` | **The Liquid line:** ```liquid {{ contact_first_name | default: "Valued Customer" | upcase }} ``` This reads left to right: take `contact_first_name`. If it's missing, use "Valued Customer" instead. Then convert whatever we have to uppercase.

What’s Next

In Module 2, you’ll learn about data types — strings, numbers, arrays, booleans, and nil/empty values. This is the single most important foundational concept for avoiding errors in Cast, and it will make every subsequent module click into place.


📖 Official documentation:

  • Overview: https://school.cast.app/liquid.html
  • Tags/Blocks: https://school.cast.app/liquid/liquid-blocks.html
  • Standard Filters: https://school.cast.app/liquid/liquid-filters.html
  • Custom Cast Filters: https://school.cast.app/liquid/custom-cast-filters.html
  • Snippet Library: https://school.cast.app/liquid/liquid-library.html

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