Math Filters

Alex Patton

Math filters do mathematical operations on numbers. Number values contain either integers (numbers without decimal points, like 2) or floats (numbers with decimal points, like 2.5). You can use math filters to do arithmetic calculations (like adding, subtracting, or dividing the value of a numeral) or change how numbers are displayed (like rounding a float up to the nearest integer). 

For instance, you could use the times filter to show the price of a product after a discount if you’re running a promotion—let’s say 25% off a $100 item. Here’s what that might look like:

Pamper your pet and save 25%! This week, our super-plush senior dog bed is just ${{ product.product_price | times: .75 }}.
Pamper your pet and save 25%! This week, our super-plush senior dog bed is just $75.00.

Pro tip: filters are applied to your key in order from left to right. That means you can do some snazzy math, but you’ll need to pay attention to the order in which you list your filters. 

Practice problem: math filters

Now let’s flex our math filter muscles to keep our discounted prices looking neat and tidy. Here’s the copy we want in the email:

Two-thirds off our newest senior dog vitamin sample—a $10 value for only $____ 

The key that contains the value is product.product price. Use the times filter (multiplies the value by a number) and round filter (rounds a number to the nearest integer or a specified number of decimals) to fill in the reduced product price.

Hint: to specify the number of decimals for the round filter, add a colon, a space, and the number of decimals to which you want to round.

Select the right Liquid code from the options below to fill in the blank:

Two-thirds off our newest senior dog vitamin sample—a $10 value for only $____

That’s not right; try again!

The correct answer is B!

Let’s run the code: 

Two-thirds off our newest senior dog vitamin sample—a ${{ product.product_price }} value for only ${{ product.product_price | times: .33 | round: 2 }}
Two-thirds off our newest senior dog vitamin sample—a $10 value for only $3.30

Why don’t the other options work?

A) It doesn’t specify the number of decimal places to which you want to round, so the filter will round to the nearest integer. The result using this code would be $3

C) Math error—the price should be reduced by two-thirds, leaving one-third left. The result using this code would be $6.60

D) The order of operations is incorrect—the rounding is done first and then the discount is applied. The result using this code would be $3.3

Up Next: Intermediate Filters – Number and Currency Filters

String Filters

Alex Patton

String filters manipulate strings. You’ll recall that a string is a sequence of characters—letters, numerals, and special characters like punctuation—like your customer’s name, a sentence, or a product ID number. Thus, for the most part, we use string filters to manage the copy in our emails. 

For example, you might use a string filter to change the case of a letter, remove unwanted whitespace, remove and/or replace words in sentences, add a line break, or add characters to the beginning or end of a string. String filters can also do things like replace characters in a string with URL-safe characters so your links work!

Let’s take a look at how the prepend filter helps us create more inviting copy to promote a product (in this case, nutritious chewy treat) by adding another string before the value, like this:

{{ product.product_name | prepend: "Be sure to reward your good boy with a " }}
Be sure to reward your good boy with a nutritious chewy treat! 

Practice problem: string filters

Ready to test your string filter skills? 

Add the new string “WOOF to our new products:” to the existing string “Your senior pet will say”. The final string should read: 

Your senior pet will say WOOF to our new products:

The key that contains the woof value is pet.pet_sound. You must use the upcase filter (converts string value to all caps) and the append filter (adds a new string after the string value). Make sure to apply them in the right order!

Select the right Liquid code from the options below:

That’s not right; try again!

The right answer is A!

Let’s run the code: 

Your senior pet will say {{ pet.pet_sound | upcase | append: "to our new products:" }}
Your senior pet will say WOOF to our new products:

Why don’t the other options work?

B) Applies the filters in the wrong order, capitalizing everything. The output would be “Your senior pet will say WOOF TO OUR NEW PRODUCTS.”

C) You must enclose the new string to be prepended in double quotes (all strings must be enclosed in double quotes).

D) You must reference the entire key: pet.pet_sound

Up Next: Intermediate Filters – Math Filters

Intermediate Filters

Alex Patton

Just got here? This module is part of a full-length Liquid tutorial. Start from the beginning.  

In this module, we’ll cover types of filters and how they work with different kinds of values:

  • String filters
  • Math filters
  • Number and currency filters
  • Array filters 

Earlier, you learned that filters change how the values of keys are displayed in emails. We experimented with the capitalize and strip filters to clean up our salutation so it looked just right. In this module, we’ll dive more deeply into filters and the myriad ways you can use them in conjunction with your keys

Let’s start out with a quick reminder of what filter notation looks like in Liquid. You place the filter after the key and use a pipe character to separate them:

{{ customer.first_name | capitalize }}
Hi Lee

Remember, whatever platform you’re using will have its own flavor of Liquid, which could include different kinds of filters. Here are a few common filters you might encounter, just to give you an idea:

  • capitalize capitalizes the first letter of the value
  • upcase capitalizes all the letters of the value
  • font_face changes the font that your value is displayed in
  • link to generates an HTML link in the text
  • format_number changes how a number value is displayed, such as adding a comma to numbers with more than three digits (aka, “4,000” instead of “4000”)

Those are some fairly simple examples; there are many, many more types of filters, some of which can get complex—especially when you use multiple filters at once! 

Though there are lots of filters, they generally fall into four common types, which you can use to affect different kinds of values in various ways. 

Up Next: Intermediate Filters – String Filters

Complex Values

Alex Patton

We’ve talked a lot about keys that point to a single value, like this:

Hi {{ name }}!
Hi Lee!

But you can also have more complex values—which allow you to do a lot of cool things with tags. The complex values are objects and arrays


An object is a value that’s made up of key/value pairs. Remember that big box labeled dessert we discussed in the Liquid Fundamentals lesson on keys—the one with many other boxes of delicious treats inside? The value of that dessert key is all the other keys and their values inside the box.    

The customer key we discussed in the first lesson of this module is also an example of a key that points to an object. Here it is again: 


As you can see, inside those single curly brackets is a collection of keys with their associated values—the whole shebang is the object

This is where that dot notation we covered in Liquid Fundamentals comes in—a key to reference the object, then another key to reference the specific value inside that big collection of key/value pairs, like this:

Hi {{ customer.first_name }}!
Hi Lee!

When you’re dealing with an object, the order of the key/value pairs inside doesn’t matter—your dot notation tells Liquid the exact value to output. 


An array also contains multiple bits of information, but instead of key/value pairs, an array contains either a list of values, which can be strings, numbers, or even objects. 

You can tell you’re looking at an array because, in JSON, it’s enclosed in square brackets instead of curly brackets. 

Let’s say we have a key called pet_names, and the value the key points to is an array.  In this example, the array is a list of strings.   

["spot", "milo", "otis"]

One of the most useful things about arrays is that they allow you to nest data. As we said, an array can also be a list of objects. That’s going to look more complicated at first. Here’s an example, in JSON, of a key called pets whose value type is an array:

[ { "name": "spot", "age": 12, "breed": "dachshund" }, { "name": "milo", "age": 7, "breed": "corgi" }, { "name": "otis", "age": 3, "breed": "whippet" } ]

Yep, looks complicated! But the principle is no different than if the array is a list of strings. Let’s break it down:

  • We see the square brackets enclose the whole thing: we know it’s an array
  • Inside the square brackets, we see sets of curly brackets: we know each set of items in curly brackets is an object
  • We know that an object contains collection of key/value pairs, and that’s exactly what we see inside each set of curly brackets!

It’s like a set of Matryoshka dolls—each element nested inside another. 

An important aspect of arrays is that the values (whether those values are strings, numbers, or objects) are organized in a specific sequence. Why does the order matter? Well as you know, the magic of Liquid comes from how keys, filters, and tags all work together. When you have a key whose value is an array, you can have filters and tags refer to the various values within it based on their specific order.

Sounds like a perfect segue into our next lesson! 

Up Next: Intermediate filters

Types of Values

Alex Patton

As we’ve discussed, keys and values come in pairs—the key points to the value (aka, the specific piece of data you have stored). 

Here are the simple types of values you’ll find in Liquid:

StringLetters, numerals, and special characters
NumberIntegers (numbers with no decimal point) and floats (numbers with a decimal point)
BooleanTrue or false flag (not a string)

Strings are composed of letters, numbers, and special characters. They must be enclosed in double quotes in JSON. For example, the email address from our customer key is a string. 


Numbers are integers (numbers with no decimal point) and floats (numbers with a decimal point). Here’s an example of a number from the customer key we looked at above:


Boolean values simply indicate whether a particular condition is true or false. For instance you might have a key called newsletter_signup, and the value would indicate whether or not a customer has signed up for your newsletter:


When a key has no value

In Liquid, a key points to a value—but sometimes your data store might be missing the value that a particular key is referencing, so there’s no value to output:

  • Nil: there is no value stored that corresponds to the key. This might happen if, say, a customer didn’t fill out their last name when they signed up for your newsletter. If you used the key {{ customer.last_name }} in that case, the value would be nil.  
  • EmptyDrop: this value will be returned if you try to use a key that’s been deleted. This doesn’t come up often.

These aren’t really types of values, in the sense that you’d never actually use a key to output them. Instead, think of them as potential circumstances that you can use a tag to account for, like back in the How Liquid Works lesson when we used a tag to output “Hi friend” if we didn’t have a value for our name key.

Up Next: Intermediate Keys – Complex Values

Understanding Key Format: JSON

Alex Patton

Time to dig into the actual code that makes up a key! First, let’s review the basics. You’ll remember this diagram of a customer key, which shows how keys and values relate:

key key value
customer first_name lee
last_name leeson

And you know that, in order to tell Liquid to output the value “Lee,” you use the following notation:

Hi {{ customer.first_name }},

Now let’s look at a slightly more complex customer key:

key value value
customer id f3bc06000001
created_at 1621454609
dob 1942-10-29T03:55:19.436507188Z
dob_clean 857592281\n\nOct 29, 1942
first_name lee
last_name leeson

Here’s the actual code that makes up that customer key:


That looks a bit different from the Liquid notation we’ve been learning—and that’s because the actual code for the key is formatted in JavaScript Object Notation, aka JSON. While we use Liquid notation to output key values, the keys themselves are formatted in JSON. 

**New terminology alert!**

We promised we’d call out any tricky vocab, and here’s a biggie: object. What we’re calling a key (in this example, it’s a key that is a collection of other keys) is called an object when we’re in JavaScript-land (e.g., the customer object): the whole bundle of names and their related values. Out in the wild, you’ll find that some documentation uses the terms key and object interchangeably. In this tutorial, we’re keeping it clear by saying key when we’re talking about Liquid notation and object when discussing JSON. 

While the terminology might get a little funky, at the end of the day, JSON is just the notation that Liquid uses to store key/value pairs—the data you keep about people, purchases, etc. The keys you use in Liquid reference specific JSON values

Up Next: Intermediate Keys – Types of Values

Intermediate Keys

Alex Patton

Just got here? This module is part of a full-length Liquid tutorial. Start from the beginning.  

In this module, we’ll cover:

  • Understanding key format: JSON
  • Types of values
  • Complex values

You already know that a key is used to reference a value. In this module, we’re going to pop the hood and look at the code that makes up a key.

Understanding just what’s what in the code allows you to see directly what you have to work with for personalizing your content. For instance, if your customer key contains a name and date of birth, you could send a personal birthday message. You’ll also learn how the values are formatted, which tells you how you can use filters and tags to affect how values are displayed.

Up Next: Intermediate Keys – Understanding key format: JSON


Alex Patton

What’s a tag?

You’ve got your personalized salutation down pat, so now it’s time to write the first sentence of our body copy—and make that personal as well. To do that, let’s talk tags (the Liquid kind, not the dog kind). 

We’ll start with a quick review. You know that a key is a container for a value, like a customer’s name. And you know that you can use filters to manipulate keysvalues, like capitalizing a customer’s name. Now we can bring in the third player on the Liquid dream team: tags

Tags use programming logic to decide which dynamic content is displayed in your email. There are lots of handy tags you can use, like the if tag to display content if certain conditions are met and the assign tag to create a key right inside your code. (We’ll explore many in depth in the Intermediate Tags module). 

One handy tag is the else/elsif tag, which will allow us to use conditional logic to choose the perfect beginning for our body copy. Let’s it put into action to get a sense of how tags work with keys.

At Tip Top Pets, you sell products for both cats and dogs. When you send an email, you want to say one thing if your customer owns a dog, but something different if they own a cat. And if you don’t know what kind of pet they have, you need a third option that covers all your bases (who knows, maybe they bought that leash for an unruly sea urchin!). 

So you come up with three sentences, one for each possible scenario. In this case, Spot is a dog, so we’re going to start the body copy with: “Ruff ruff! We’ve received your order!” We know Spot is a dog because “dog” is the value of the pet.pet_type key

Let’s see how the key and the tag work together to dynamically select the right content:

{% if pet.pet_type == "dog" %}
Ruff ruff! We’ve received your order!
{% elsif pet.pet_type == "cat" %}
Meow! We’ve received your order!
{% else %}
Hooray! We’ve received your order!
{% endif %}
Ruff ruff! We’ve received your order!

The tag will choose the correct text for a cat or a dog, or generic text if pet.pet_type has a value other than cat or dog.

Practice problem

Ready to write some code? Use the if/elsif tag to add a personalized message based on Spot’s age category. For seniors, it should say “Senior pets need tender care.” For puppies, it should say “Puppies need a strong start.” For everyone else, it should say “Your pet deserves the best.”

Select the correct Liquid code from the options below:

That’s not right; try again!

Option A is correct!

Let’s run the code:

{% if pet.pet_age == "senior" %}
Senior pets need tender care.
{% elsif pet.pet_age == "puppy" %}
Puppies need a strong start.
{% else %}
Your pet deserves the best.
{% endif %}
Senior pets need tender care.

Teamwork makes the dreamwork, so let’s look at how to use tag notation to make it play nice with keys and tags!

Tag notation

In Liquid, tags are surrounded by single curly brackets and percentage signs, like this:

{% tag %}

Unlike keys, tags do not display a value to the email recipient. Instead, they provide the logic that determines what is displayed. In general, tags use true-or-false (aka, Boolean) logic to determine the output to display: telling Liquid that if a certain condition is true, display a certain output, and if the condition is false, move on. 

Tags sometimes contain logical and comparison operators (like == in the previous section). These operators are how the tag chooses what to display. We’ll cover operators in more detail later, but here’s a quick overview of the basic operators.

!=does not equal
>greater than
<less than
>=greater than or equal to
<=less than or equal to
orlogical or
andlogical and

There’s much more to learn about Liquid, but now you have a basic understanding of how keys, filters, and tags work together to add personalized, dynamic content to your static email templates.  

Up Next: Intermediate Keys


Alex Patton

What’s a filter?

You already know that a key is a container for a value, like a customer’s name. Sometimes that’s all you need to personalize an email! 

But you may also want to manipulate how keys are displayed to make your email better. To give a few examples, you might want to:

  • capitalize a word (like a person’s name)
  • calculate the end date of a free trial 
  • convert a timestamp to a date that’s easy on the eyes

That’s where Liquid filters come in—they change how values are displayed in emails. It’s teamwork time for Liquid components!

The capitalize filter is a great place to start. It’s just what it sounds like—it capitalizes the first letter of the key’s value when it’s displayed in your email. 

Here’s our code and output again without a filter:

Hi {{ customer.first_name }},
Hi lee,

And here’s what happens when we apply the capitalize filter to our customer.first_name key:

Hi {{ customer.first_name | capitalize }},
Hi Lee,

There are many types of filters you can use to manipulate how the values of your keys are displayed—such as strip to take out extra whitespace and upcase to capitalize all the letters.

Practice problem 

Your turn! Remember the extra spaces after Spot’s name in the first lesson in this module? Let’s fix them too, using the strip filter.

Select the right Liquid code from the options below:

That’s not right; try again!

The right answer is C!

Let’s run the code and see what happens:

Hi {{ customer.first_name | capitalize }} (and {{ pet.pet_name | strip }})!
Hi Lee and Spot!

Now we’re getting somewhere! We’ve got a super-personalized email salutation that’s nicely formatted. Now let’s get totally clear on filter notation in Liquid.

Filter notation

Filters always go after the key, inside the double curly braces. Separate filters from the key with a pipe character, like this:

{{ key.key | filter }}

You can use as many filters as you like for each key. Liquid will apply the filters in order from left to right: 

{{ key.key | filter | filter }}

Sometimes the order in which filters are listed makes no difference—like when you apply the capitalize and strip filters to the same key to capitalize a name and get rid of ugly whitespace. But as you’ll learn later (in the Intermediate Filters module), sometimes filters do more complex manipulations (like math calculations). In that situation, filter order matters a lot—so just file that nugget away in your brain for later!

Up Next: Liquid Fundamentals – Tags


Alex Patton

What’s a key? 

At its simplest, a key is a container for a value

Imagine a box labeled favorite_cake. You open the box, and inside is a red velvet cake. In this analogy, the box is the key, and “Red Velvet Cake” is the value. In Liquid, it looks like this:

{{ favorite_cake}}
Red Velvet Cake

Keys can also contain other keys. This time, imagine a box labelled dessert. Inside it, you might find seven boxes, with labels like, pie, cake, ice_cream, and so on—all those desserts are keys inside the dessert key. Nestled inside the cake box, you would find many additional boxes with different kinds of cake, including one labeled favorite_cake. In this situation, here’s how it would look in Liquid if you want to output the value of favorite_cake

{{ dessert.cake.favorite_cake }}
Red Velvet Cake

FYI, when we use keys that contain other keys, we’ll be dealing with JavaScript Object Notation (JSON). JSON is just the format used for the code; we’ll look at it in more detail in the Intermediate Keys module.  

Now let’s apply this delicious metaphor to the real-life scenario from the How Liquid Works lesson: the customer who’s just ordered a dog leash from your online store, Tip Top Pets. 

You’re preparing a confirmation email to go out whenever a customer makes a purchase, which will have both static (always the same) and dynamic (personalized for each individual email) content. You have the following keys, or “boxes” of information, about your client. In this example, each box of information contains other boxes of information (i.e., each key contains several other keys, like we saw in the desserts example above).

key key value
customer first_name lee
last_name leeson
key key value
pet pet_type dog
pet_name Spot

As you can see, some keys contain a collection of keys (like the pet key), and other keys point to individual values (like the pet_name key). So if you want to output the value of the pet_name key, you have to first open the big box (the pet key), then open the little box inside (the pet_name key) to get the value (Spot) that you want to output. You can also think of it like a parent-child relationship—you reference the “parent” key to get to the “child” key.   

Let’s see that in action. To include the dog’s name in your email, you must reference both pet and pet_name. Here’s our Liquid code and output:

Hope {{ pet.pet_name }} loves your purchase!
Hope Spot loves your purchase!

Practice problem

Ready to test your skills with a practice problem? Let’s say hi to both our customer and our doggy friend Spot in the salutation. Select the right Liquid code from the options below:

That’s not right; try again!

The right answer is A!

Now we’ll run the code and see what happens:

Hi {{ customer.first_name }} and {{ pet.pet_name }}!
Hi lee and Spot  !

Our email is coming along! You’ve probably noticed the problems with capitalization and extra whitespace, and we’re going to fix them in the next section with a filter. But before we do, let’s talk about key notation in Liquid.

Key notation

When we say notation, we’re referring to the specific format—like punctuation and spaces—that you must use for your keys. In Liquid, keys are surrounded by double curly brackets, like this:

{{ key }}

The double curly brackets cue Liquid to display the key’s value in your email. It’s common to put a space on either side of the key because it makes your code easier to read, but you can leave the spaces out without breaking anything.

If you are referencing a key that contains other keys, use dot notation—that is, include a period to separate each key, like this:

{{ pet.pet_type }}

Key names must be made up of letters and numbers only, and we strongly recommend that you use an underscore instead of a space when creating key names, like this: pet_name. Why the spacebar hate? If you include spaces in key names, you must enclose the key in square brackets every time you reference it or your code will break. Here’s how that looks:

{{ pet.[pet name] }}

But why give yourself more work and increase the risk of broken code? Replace those spaces and have one fewer thing to worry about!

Now you know how to use simple keys, and you understand key notation. Now let’s fix up our text with a basic filter.

Up Next: Liquid Fundamentals – Filters

Our mailing list is chock full of tactical lifecycle marketing how-tos, interviews with trending internet businesses, and product updates.