Liquid

Read time: 10 minutes | Learn the lightweight email templating language.

Jonny Richardson avatar
Written by Jonny Richardson
Updated over a week ago

Liquid is a lightweight email-templating language that can supercharge your email templates in Engage. Liquid uses a mixture of conditions, objects, and tags inside email templates to present readers with dynamic content.

Created by Shopify and shared as an open-source project on GitHub, it has achieved popularity owing mainly to its ease of use and super powerful outputs.

On this page, we'll begin to get to grips with Liquid, share some game-changing examples of how it might be used, and provide further reading for those keen to master its intricacies.

Getting started

Liquid at-a-glance:

  • All clients with access to emails within Engage can use Liquid.

  • Liquid can be used with any Engage email type (Basic Editor, Drag & Drop, and Import HTML)

  • Liquid allows you to personalize emails and display dynamic content based on information you know or can calculate about the student receiving the message.

Objects

In Gecko and Liquid, objects are the name given to syntax that uses double curly braces '{{ }}' to display dynamic content via mailmerge tags.

e.g.,

Hi {{contact.full_name.first_name}},

In the example above, the result would be the object/tag returning the student's first name.

e.g.,

Hi Samantha,

Tags

The use of tags is what enables Liquid to execute logic or conditions. Here, you'll want to encase your logic in a mixture of curly braces and percentage signs '{% %}'.

e.g.,

{% if contact.age <= 16 %}
Make sure to ask your parent/guardian to attend Open House with you.
{% else %}
We look forward to meeting you at Open House!
{% endif %}

πŸ’‘ Important: When using tags, make sure not to add any additional curly braces '{ }' or parentheses '( )' as this will break the tag syntax. Gecko contact fields can be called without curly braces (like with contact.age in the example above) whilst referenced in tags.

Filters

Filters can be used within Liquid to modify or change how objects are displayed.

e.g.,

{{ "hello" | capitalize }}

Would output as:

Hello

Later in the article, we include an example of where using a downcase filter proves to be extremely helpful.

Let's combine what we've learned to create an example you can copy into your template and test:

Hi {{contact.full_name.first_name}},

Thanks for testing out our liquid template!

{% if contact.total_emails == 0 %}
πŸ‘‹ Welcome to Gecko! I can see this is the first email you've received!
{% else %}
🀩 It looks like this isn't the first email we've sent you from Gecko. Thanks for being part of the family!
{% endif %}

Regards,

The crux of this example is that we check the Gecko contact field, {{contact.total_emails}}, to see whether a student has received an email from us before.

If this is the first email the student has received from Gecko, they'll get a welcome message. If they've been emailed before, they'll be thanked for being a long-time part of the family.

One of Liquid's (many) strengths is that it can be used with your email's HTML. You can easily use Liquid to set the conditions that need to arise for specific parts of your HTML to be displayed:

{% if isCurrentStudent == true %} 
<h2>Can't wait to chat about {{contact.subj_of_interest}}!</h2>
<div>Here's a <a href="#">cool link</a> you can read.</div>
{% else %}
<h2>Signup for a Virtual Open Day</h2>
<div>Fill out the form below to signup for an Open Day</div>
<form>.....</form>
{% endif %}

Examples

Let's skip to the good bit. In this section, we'll share some examples of how Liquid can streamline your communications and, in some cases, open doors that were previously shut!

1: Using Liquid to send A/B testing emails

Goal: 50% of users who finish my form get email A, and the other 50% get email B.

Difficulty: πŸ₯ Easy

Example code:

{% assign result = response.id | modulo: 2 %} 
{% if result == 0 %}
πŸ…°οΈ You're an A tester! A template goes here.
{% else %}
πŸ…±οΈ You're a B tester! B template goes here.
{% endif %}

Explanation: Whenever a student submits a response to a form, Gecko will generate a response ID for them. This response ID incrementally increases with every form submission.

The plan is to check the response ID: if it's even, we'll display the A template text. If the response ID is odd, we'll show the B template text instead.

In the first line of our code, we create a variable called 'result' and then fill it with the output of response.id modulo 2.

{% assign result = response.id | modulo: 2 %}

Modulo is a unique filter in that it returns the remainder of a division operator. To put that into context, imagine that our response.id is an even number like 2464. If we divide 2464 / 2, the result is nice and clean - exactly 1232, with no remainder.

If, on the other hand, our response.id is an odd number, like 3451, then dividing 3451 / 2, results in an awkward 1725.5. Crucially, the division wasn't clean, and we have a reminder of .5.

In the second line of code, we check the result variable:

{% if result == 0 %} 

Suppose the result has been a clean division (like you'd always get from dividing an even response ID by 2). In that case, we'd print email A.

πŸ…°οΈ You're an A tester! A template goes here. 

If the result hadn't been a clean division (like you'd always get from dividing an odd response ID by 2), then we'd trigger the else statement and print email B instead:

{% else %} 
πŸ…±οΈ You're a B tester! B template goes here.
{% endif %}

2: Sharing events based on the student's location

Goal: If a student resides in a state your recruiters are visiting soon, tell them about the visit! Otherwise, share upcoming virtual event information.

Difficulty: πŸ₯ Easy

Example code:

{% assign state = contact.address.state %}
{% if state == "California" %}
🌴 Hi contact.full_name.first_name! We'll be in California next week for an info session. It's a great opportunity to meet our team and get your questions answered. RSVP here.
{% else %}
πŸ‘©β€πŸ’» Greetings! Get your laptop ready as we've got some fantastic virtual events coming soon. Learn more here.
{% endif %}

Explanation: In this particular example, I have a recruiter who will visit California soon. I want to tell any students living in California about the event and invite them to RSVP. For everyone not in California, I want the same email to promote upcoming virtual event offerings instead.

To make this example work, we will evaluate a Gecko address contact field.

{% assign state = contact.address.state %}

In the first line, we create a variable named 'state'. We then make the state variable equal to whatever value is present in the student's State field on their address contact field.

{% if state == "California" %} 
🌴 Hi contact.full_name.first_name! We'll be in California next week for an info session. It's a great opportunity to meet our team and get your questions answered. RSVP here.

In the following line, we tell Liquid to evaluate the state variable. If it is precisely equal to California, we print the information about the recruiter event and share a link to let the student register for the event directly.

{% else %} 
πŸ‘©β€πŸ’» Greetings! Get your laptop ready as we've got some fantastic virtual events coming soon. Learn more here.
{% endif %}

We then throw the proverbial uno reverse card and say that for everyone else (not lucky enough to live in sunny California!) we instead want to share information about our virtual events.

3: Academic advice based on credits earned

Goal: Send a different email to a student based on their current academic performance.

Difficulty: πŸ₯ Easy

Example code:

{% if contact.credits_earned < 60 %} 
Hi {{contact.full_name.first_name}}, πŸ’ͺ You've earned {{contact.credits_earned}} so far! Once you reach 60, you'll be halfway to graduation. Keep it up!
{% else %}
Hi {{contact.full_name.first_name}}, 🀩 Amazing work on earning {{contact.credits_earned}} so far! We'd strongly recommend reaching out to your advisor to discuss your graduation prep.
{% endif %}

Explanation: Our academic support team has asked us to send different emails to students based on how many credits they've earned thus far. Luckily, we know Liquid and can achieve this with one template instead of multiple!

{% if contact.credits_earned < 60 %} 

In the first line of our code, we tell Liquid to evaluate our Gecko contact field, which houses their current credits. If the number of credits is less than (<) 60, we want to print the following message in our email:

Hi {{contact.full_name.first_name}}, πŸ’ͺ You've earned {{contact.credits_earned}} so far! Once you reach 60, you'll be half-way to graduation. Keep it up! 

Note that when we're printing text directly to the student, we still need to use the correct Gecko template tag syntax of using double curly braces. This isn't needed when using Gecko tags within Liquid arguments (such as in line one of this template when we referenced {{contacts.credits_earned}}).

{% else %} 
Hi {{contact.full_name.first_name}}, 🀩 Amazing work on earning {{contact.credits_earned}} so far! We'd strongly recommend reaching out to your advisor to discuss your graduation prep.
{% endif %}

As with our previous template, if the student has earned 61 or more credits, we're instead going to share a message giving them information about how they can start preparing for graduation!

4: Sending subject-specific information

Goal: Provide dynamic, subject-specific information about a student's chosen program/major/course of interest.

Difficulty: πŸ“šIntermediate

Example code:

{% assign subject = contact.program_of_interest | downcase %} 
{% if subject contains "law" %}
πŸ‘©πŸΎβ€βš–οΈ Here's information about law.
{% elsif subject contains "chemistry" %}
πŸ§ͺ Here's some chemistry stuff.
{% elsif subject == "entrepreneurial finance" or subject == "finance" or subject == "fundamentals of finance" %}
πŸ’° Here's some information about monneeeyy
{% elsif subject == "aerospace engineering" %}
πŸš€ Here's some information about rockets.
{% else %}
πŸ€·β€β™€οΈ Good luck with {{ contact.program_of_interest }}.
{% endif %}

Explanation: A specific, highly tailored email will beat a generic one every time. Liquid is well placed to allow us to evaluate a student's chosen subject of interest and include program-specific information in their email template.

{% assign subject = contact.program_of_interest | downcase %} 

In the first line, we create a variable called 'subject', and in it, we'll pass the contents of our Gecko contact field, which contains the student's selected program of interest. Before we pass the value, we first downcase it (removing any capital letters). This will make the next steps far, far more simpler.

{% if subject contains "law" %} 
πŸ‘©πŸΎβ€βš–οΈ Here's information about law.

The first clause to evaluate is whether or not our subject variable contains the phrase "law". In practice, this means if the phrase "law" appears anywhere in the program_of_interest (e.g., International Law and Practice, US, International and Transnational Law, Law studies, etc.), the student will receive the information about law.

{% elsif subject contains "chemistry" %} 
πŸ§ͺ Here's some chemistry stuff.

As above, but for Chemistry. As we have more than one if statement, we use elsif. Again, using subject contains means that we look for the phrase chemistry throughout the program_of_interest value (e.g., Molecular Biochemistry and Biophysics, Bioanalytical Chemistry, etc.)

{% elsif subject == "entrepreneurial finance" or subject == "finance" or subject == "fundamentals of finance" %} 
πŸ’° Here's some information about monneeeyy

We're mixing things up a bit. Whilst still using an elsif statement, we're looking for three exact matches on program_of_interest. To put plainly - if the student has a program of interest of entrepreneurial finance, OR, finance, OR, fundamentals of finance, they'll see the finance-specific information. If the student has a different value, not included in the elsif statement, like Corporate Finance, they'll not meet the condition.

{% elsif subject == "aerospace engineering" %} 
πŸš€ Here's some information about rockets.

As mentioned above, but this time, if the student has selected a particular aerospace engineering program, they'll get some information about rockets.

{% else %} 
πŸ€·β€β™€οΈ Good luck with {{ contact.program_of_interest }}.
{% endif %}

Finally, we reach the end of our Liquid template, and we round it off with the else statement. If the student fails to meet any of the conditions we've described, we have a catch-all statement, which gives generic information to everyone else!

5: Better event communication

Goal: Gently remind students who are 'Invited' to sign up. Hype up those who are 'Registered'. Ask those who have 'Cancelled' to re-book another event.

Difficulty: πŸ“šIntermediate

Example code:

{% if contact.status == "Invited" %} 
πŸ‘€ {{contact.full_name.first_name}} you've still not told us if you're attending! RSVP here.
{% elsif contact.status == "Registered" %}
🀩 Thanks for registering, {{contact.full_name.first_name}}. We can't wait to see you on {{event.start_date.time_12hr}}!
{% elsif contact.status == "Cancelled" %}
😒 We were sorry to learn you won't join us this time, {{contact.full_name.first_name}}. But worry not! Book another event here {% endif %}

Explanation: We're big fans of using Gecko to send before or after event workflows. Liquid allows us to make our templates even more dynamic. The first status we want to check is whether a student is invited:

{% if contact.status == "Invited" %} 
πŸ‘€ {{contact.full_name.first_name}} you've still not told us if you're attending! RSVP here.

If the student's contact.status within the event is exactly equal to 'Invited' in the event that this template is sent from, the student will get a message linking them to their RSVP page, and asking them to confirm they'll attend.

{% elsif contact.status == "Registered" %} 
🀩 Thanks for registering, {{contact.full_name.first_name}}. We can't wait to see you on {{event.start_date.time_12hr}}!

If (or elsif, to be more exact...), on the other hand, the student is marked as 'Registered', we'll thank the student for registering, and provide them with further information about the event.

{% elsif contact.status == "Cancelled" %} 
😒 We were sorry to learn you won't join us this time, {{contact.full_name.first_name}}. But worry not! Book another event here {% endif %}

Finally, we check to see if the student is now 'Cancelled'. If so, we will share a form inviting them to book another event!

6: Turn your email into a UCAS point calculator

Goal: Use a Gecko form to input their exam results. Grade their results, similar to the UCAS calculator, and use Liquid to encourage the students to continue their application or reject them based on the results.

Difficulty: 😈 Hard

Example code:

{%- assign ucas_total = 0 -%}

{%- case response.grade_1 -%}
{%- when 'A*' -%}
{%- assign ucas_total = ucas_total | plus: 56 -%}
{%- when 'A' -%}
{%- assign ucas_total = ucas_total | plus: 48 -%}
{%- when 'B' -%}
{%- assign ucas_total = ucas_total | plus: 40 -%}
{%- when 'C' -%}
{%- assign ucas_total = ucas_total | plus: 32 -%}
{%- when 'D' -%}
{%- assign ucas_total = ucas_total | plus: 24 -%}
{%- when 'E' -%}
{%- assign ucas_total = ucas_total | plus: 16 -%}
{%- endcase -%}

{%- case response.grade_2 -%}
{%- when 'A*' -%}
{%- assign ucas_total = ucas_total | plus: 56 -%}
{%- when 'A' -%}
{%- assign ucas_total = ucas_total | plus: 48 -%}
{%- when 'B' -%}
{%- assign ucas_total = ucas_total | plus: 40 -%}
{%- when 'C' -%}
{%- assign ucas_total = ucas_total | plus: 32 -%}
{%- when 'D' -%}
{%- assign ucas_total = ucas_total | plus: 24 -%}
{%- when 'E' -%}
{%- assign ucas_total = ucas_total | plus: 16 -%}
{%- endcase -%}

{%- case response.grade_3 -%}
{%- when 'A*' -%}
{%- assign ucas_total = ucas_total | plus: 56 -%}
{%- when 'A' -%}
{%- assign ucas_total = ucas_total | plus: 48 -%}
{%- when 'B' -%}
{%- assign ucas_total = ucas_total | plus: 40 -%}
{%- when 'C' -%}
{%- assign ucas_total = ucas_total | plus: 32 -%}
{%- when 'D' -%}
{%- assign ucas_total = ucas_total | plus: 24 -%}
{%- when 'E' -%}
{%- assign ucas_total = ucas_total | plus: 16 -%}
{%- endcase -%}

{%- case response.grade_4 -%}
{%- when 'A*' -%}
{%- assign ucas_total = ucas_total | plus: 56 -%}
{%- when 'A' -%}
{%- assign ucas_total = ucas_total | plus: 48 -%}
{%- when 'B' -%}
{%- assign ucas_total = ucas_total | plus: 40 -%}
{%- when 'C' -%}
{%- assign ucas_total = ucas_total | plus: 32 -%}
{%- when 'D' -%}
{%- assign ucas_total = ucas_total | plus: 24 -%}
{%- when 'E' -%}
{%- assign ucas_total = ucas_total | plus: 16 -%}
{%- endcase -%}

{%- if ucas_total >= 135 -%}

⭐️ Based on your UCAS points tally of {{ucas_total}}, we'd be delighted to invite you to continue your application here

{%- else -%}

😞 Thanks for your interest in Gecko University! Sadly, based on your UCAS points tally of {{ucas_total}}, you'd not be eligible to study with us. We wish you luck for the future.

{%- endif -%}

Explanation: Good news: this isn't anywhere near as complex as it might look at first glance! For this method to work, my form is set up to capture each exam result grade in a separate field. Each grade field has a template tag of grade_1, grade_2, grade_3, and grade_4.

{%- assign ucas_total = 0 -%}

In our first line, we're instructing Liquid to create a variable called 'ucas_total' and to assign the value of 0 to it.

{%- case response.grade_1 -%}

For the next few lines, we're creating a case that will allow us to take the response.grade_1 value (the grade the student entered into the first Grade field on our form) and then evaluate it against various criteria.

{%- when 'A*' -%}
{%- assign ucas_total = ucas_total | plus: 56 -%}

The first variable we check is whether grade_1 has a value of A* - the highest grade achievable. If this check evaluates to true, we call back to the 'ucas_total' variable we created on line one, and we take whatever is in it (initially a value of 0), and we add 56 to it.

{%- when 'A' -%}
{%- assign ucas_total = ucas_total | plus: 48 -%}

If, on the other hand, the grade wasn't A*, we look to the next when statement, and look to see if the grade is A, instead. If this evaluates to true, we add 48 to the ucas_total variable.

{%- assign ucas_total = ucas_total | plus: 48 -%}
{%- when 'B' -%}
{%- assign ucas_total = ucas_total | plus: 40 -%}
{%- when 'C' -%}
{%- assign ucas_total = ucas_total | plus: 32 -%}
{%- when 'D' -%}
{%- assign ucas_total = ucas_total | plus: 24 -%}
{%- when 'E' -%}
{%- assign ucas_total = ucas_total | plus: 16 -%}
{%- endcase -%}

We then do the same for all of the other scores before ending the case. Let's recap what has just happened:

  • We've created a variable called ucas_total with a value of 0

  • We've taken the output of the response.grade_1 field and iterated it through a case where we compare its value against all available grades

  • When the correct grade is matched, we add the corresponding grade value (according to the UCAS calculator) to the ucas_total variable

Now, all we need to do is to run the same case for the next grade field on the form:

{%- case response.grade_2 -%}
{%- when 'A*' -%}
{%- assign ucas_total = ucas_total | plus: 56 -%}
{%- when 'A' -%}
{%- assign ucas_total = ucas_total | plus: 48 -%}
{%- when 'B' -%}
{%- assign ucas_total = ucas_total | plus: 40 -%}
{%- when 'C' -%}
{%- assign ucas_total = ucas_total | plus: 32 -%}
{%- when 'D' -%}
{%- assign ucas_total = ucas_total | plus: 24 -%}
{%- when 'E' -%}
{%- assign ucas_total = ucas_total | plus: 16 -%}
{%- endcase -%}

...and we repeat the process for grade_3 and grade_4.

{%- if ucas_total >= 135 -%}

⭐️ Based on your UCAS points tally of {{ucas_total}}, we'd be delighted to invite you to continue your application here

Once done, we draw our line in the sand. How many UCAS points constitute enough for you to want the student to continue their application? In this example, we check whether the student's grades are greater than or equal to 135 UCAS points. If this evaluates to true, we print information encouraging them to apply and send them to the following pre-filled form.

{%- else -%}

😞 Thanks for your interest in Gecko University! Sadly, based on your UCAS points tally of {{ucas_total}}, you'd not be eligible to study with us. We wish you luck for the future.

{%- endif -%}

Finally, for students who don't meet the UCAS point total, we thank them for their interest and reject them using the same template.

Webinar

Learn Liquid in 30 Minutes was recorded on October 5th, 2023. It serves as a super introduction to Liquid.

Further reading


Any questions? Start a live chat with a support team member, or feel free to explore the rest of our academy. Spotted an error or want to suggest a future article for the academy? Let us know here.

Did this answer your question?