Filters are one of Liquid's most powerful features, transforming raw data into polished, formatted output. While keys give you access to data and operators let you compare it, filters let you modify and format it in countless ways, all without changing the underlying values.
What are Liquid filters?
Filters are data transformation functions that modify the output of keys without changing the source data. Think of filters as a pipeline: data flows in, gets transformed, and flows out in a new format. This functional approach keeps your templates clean, predictable, and maintainable.
The syntax is builds on itself. Filters are applied using the pipe character | after a key:
{{ user.name | upcase }}Some filters can accept parameters for more control:
{{ article.content | truncate: 100 }}And most powerfully, filters can be chained together, with the output of one filter becoming the input of the next:
{{ user.bio | strip_html | truncate: 200 | append: "..." }}Let's explore the different categories of filters and how to use them effectively in your notification templates.
String filters
String filters are your primary tool for text formatting and manipulation. They handle everything from capitalization to HTML stripping.
Capitalization filters
Control how text is capitalized with these filters:
capitalize- Capitalizes the first letter of the entire stringupcase- Converts all letters to uppercasedowncase- Converts all letters to lowercase
{
"user": {
"name": "sarah chen",
"company": "acme corp"
}
}{{ user.name | capitalize }}
{{ user.name | upcase }}
{{ user.name | downcase }}
{{ user.company | capitalize }}Sarah chen
SARAH CHEN
sarah chen
Acme corpNote that capitalize only capitalizes the first letter of the entire string, not each word.
Truncation and trimming
Shorten or clean up text with these filters:
truncate- Cuts text at a certain character count, optionally with custom endingtruncatewords- Cuts text at word boundaries for cleaner breaksstrip- Removes leading and trailing whitespace
{
"article": {
"title": "The Ultimate Guide to Liquid Templating for Notifications",
"excerpt": " Learn how to create dynamic templates "
}
}{{ article.title | truncate: 30 }}
{{ article.title | truncate: 30, "..." }}
{{ article.title | truncatewords: 5 }}
{{ article.excerpt | strip }}The Ultimate Guide to Liq...
The Ultimate Guide to Liq...
The Ultimate Guide to Liquid...
Learn how to create dynamic templatesHTML and special character handling
Clean up or escape HTML content with these filters:
strip_html- Removes all HTML tags from a stringescape- Escapes special characters like&,<,>into HTML entities
{
"comment": {
"text": "<p>This is <strong>great</strong>!</p>",
"username": "Sarah & John"
}
}{{ comment.text | strip_html }}
{{ comment.username | escape }}
This is great!
Sarah & John
String replacement and manipulation
Replace or remove parts of strings with these filters:
replace- Replaces all occurrences of a substring with another stringremove- Removes all occurrences of a substringsplit- Splits a string into an array based on a delimiterjoin- Joins array elements into a single string with a separator
{
"product": {
"name": "Super Widget Pro",
"sku": "SW-PRO-2024"
}
}{{ product.name | replace: "Super", "Ultra" }}
{{ product.name | remove: " Pro" }}
{{ product.sku | replace: "-", "_" }}
{{ product.name | split: " " | join: "-" | downcase }}Ultra Widget Pro
Super Widget
SW_PRO_2024
super-widget-proString utilities
Additional useful string transformations:
slugify- Converts a string to URL-friendly format (lowercase, dashes instead of spaces)url_encode- Encodes special characters for safe use in URLsappend- Adds text to the end of a stringprepend- Adds text to the beginning of a string
{
"url": {
"path": "blog posts and articles",
"params": "[email protected]"
}
}{{ url.path | slugify }}
{{ url.params | url_encode }}
{{ "hello" | append: " world" }}
{{ "goodbye" | prepend: "Say " }}blog-posts-and-articles
user%40example.com
hello world
Say goodbyeNumeric filters
Numeric filters handle mathematical operations and number formatting.
Mathematical operations
Perform calculations directly in your templates with these filters:
plus- Adds a number to the inputminus- Subtracts a number from the inputtimes- Multiplies the input by a numberdivided_by- Divides the input by a numbermodulo- Returns the remainder of divisionround- Rounds to the nearest integer or specified decimal places
{
"product": {
"price": 99.99,
"quantity": 3,
"tax_rate": 0.08
}
}Subtotal: ${{ product.price | times: product.quantity }}
Tax: ${{ product.price | times: product.quantity | times: product.tax_rate }}
Total: ${{ product.price | times: product.quantity | times: 1.08 | round: 2 }}
Price per item: ${{ 299.97 | divided_by: 3 | round: 2 }}
With $10 discount: ${{ product.price | minus: 10 }}
Price increase: ${{ product.price | plus: 20 }}Subtotal: $299.97
Tax: $23.9976
Total: $323.97
Price per item: $99.99
With $10 discount: $89.99
Price increase: $119.99Available math filters: plus, minus, times, divided_by, modulo.
Rounding and formatting
Control decimal precision and number display with these filters:
round- Rounds to specified decimal places (default: 0)ceil- Rounds up to the nearest integerfloor- Rounds down to the nearest integerat_least- Ensures a number is at minimum the specified valueat_most- Ensures a number doesn't exceed the specified value
{
"metrics": {
"conversion_rate": 0.15789,
"revenue": 1234567.89,
"percentage": 67.5
}
}{{ metrics.conversion_rate | times: 100 | round: 2 }}%
{{ metrics.conversion_rate | times: 100 | round: 1 }}%
{{ metrics.conversion_rate | times: 100 | ceil }}%
{{ metrics.conversion_rate | times: 100 | floor }}%
Revenue: ${{ metrics.revenue | round }}
{{ metrics.percentage | at_least: 50 }}
{{ metrics.percentage | at_most: 100 }}15.79%
15.8%
16%
15%
Revenue: $1234568
67.5
67.5The at_least and at_most filters ensure a number stays within bounds.
Array filters
Array filters help you manipulate and extract data from collections.
Extracting array elements
Access specific elements or properties with these filters:
first- Returns the first element of an arraylast- Returns the last element of an arraymap- Extracts a single property from each object in an arrayjoin- Combines array elements into a single string with a separator
{
"products": [
{
"name": "Laptop",
"price": 999,
"category": "electronics"
},
{
"name": "Desk",
"price": 399,
"category": "furniture"
},
{
"name": "Chair",
"price": 299,
"category": "furniture"
}
]
}First: {{ products | first | map: "name" }}
Last: {{ products | last | map: "name" }}
All names: {{ products | map: "name" | join: ", " }}
All prices: {{ products | map: "price" | join: " | $" | prepend: "$" }}First: Laptop
Last: Chair
All names: Laptop, Desk, Chair
All prices: $999 | $399 | $299The map filter extracts a single property from each object in an array, creating a new array of just those values.
Sorting and filtering arrays
Organize and refine collections with these filters:
sort- Sorts array elements by a property or valuereverse- Reverses the order of array elementsuniq- Removes duplicate values from an arraysize- Returns the number of elements in an array
{
"users": [
{
"name": "Charlie",
"score": 85,
"active": true
},
{
"name": "Alice",
"score": 92,
"active": true
},
{
"name": "Bob",
"score": 78,
"active": false
}
],
"tags": [
"ruby",
"python",
"ruby",
"javascript",
"python"
]
}Alphabetical: {{ users | sort: "name" | map: "name" | join: ", " }}
By score: {{ users | sort: "score" | map: "name" | join: ", " }}
Reversed: {{ users | sort: "score" | reverse | map: "name" | join: ", " }}
Unique tags: {{ tags | uniq | sort | join: ", " }}
Tag count: {{ tags | size }}
Unique count: {{ tags | uniq | size }}Alphabetical: Alice, Bob, Charlie
By score: Bob, Charlie, Alice
Reversed: Alice, Charlie, Bob
Unique tags: javascript, python, ruby
Tag count: 5
Unique count: 3Array operations
Combine and analyze arrays with these filters:
join- Combines array elements into a single string with a separatorsize- Returns the number of elements in an arraycompact- Removesnilvalues from an arraysort- Sorts array elements in ascending order
{
"order": {
"items": [
"Laptop",
"Mouse",
"Keyboard"
],
"quantities": [
1,
2,
1
]
},
"numbers": [
5,
2,
8,
1,
9,
3
]
}Item list: {{ order.items | join: ", " }}
Items with quantity: {{ order.items | join: " & " }}
Total items: {{ order.items | size }}
Compact list: {{ order.items | compact | join: ", " }}
Sorted numbers: {{ numbers | sort | join: " < " }}Item list: Laptop, Mouse, Keyboard
Items with quantity: Laptop & Mouse & Keyboard
Total items: 3
Compact list: Laptop, Mouse, Keyboard
Sorted numbers: 1 < 2 < 3 < 5 < 8 < 9The compact filter removes nil values from arrays.
Date filters
Date filters are essential for formatting timestamps in user-friendly ways.
Basic date formatting
Format dates using strftime patterns with the date filter:
date- Formats timestamps using strftime format codes
{
"event": {
"start_time": "2024-12-25T15:30:00Z",
"created_at": "2024-01-15T09:00:00Z"
}
}{{ event.start_time | date: "%B %d, %Y" }}
{{ event.start_time | date: "%m/%d/%Y" }}
{{ event.start_time | date: "%A, %b %d at %I:%M %p" }}
{{ event.start_time | date: "%Y-%m-%d" }}December 25, 2024
12/25/2024
Wednesday, Dec 25 at 03:30 PM
2024-12-25Common format codes:
%Y- 4-digit year (2024)%m- Month (01-12)%d- Day (01-31)%B- Full month name (December)%b- Abbreviated month (Dec)%A- Full day name (Wednesday)%I- 12-hour format (01-12)%H- 24-hour format (00-23)%M- Minutes (00-59)%p- AM/PM
Default values
Provide fallback values when data is missing or empty:
default- Returns a fallback value when the input isnilorfalse
{
"user": {
"first_name": "Sarah",
"nickname": null,
"bio": ""
}
}Hello, {{ user.first_name | default: "there" }}!
Nickname: {{ user.nickname | default: "No nickname set" }}
Bio: {{ user.bio | default: "No bio provided" }}
Missing: {{ user.phone | default: "Not provided" }}Hello, Sarah!
Nickname: No nickname set
Bio:
Missing: Not providedNote that default only applies when a value is nil or false—empty strings are still truthy, so they won't trigger the default.
Chaining filters
The real power of filters emerges when you chain them together. Each filter's output becomes the next filter's input:
{
"article": {
"title": "understanding liquid templating",
"content": "<p>This is a <strong>great article</strong> about Liquid that goes into extensive detail about all the features.</p>",
"tags": [
"liquid",
"templating",
"liquid",
"notifications"
]
}
}{{ article.title | capitalize | append: " - A Complete Guide" }}
{{ article.content | strip_html | truncate: 50 }}
{{ article.tags | uniq | sort | join: ", " | upcase }}Understanding liquid templating - A Complete Guide
This is a great article about Liquid that goes ...
LIQUID, NOTIFICATIONS, TEMPLATINGPractical chaining examples
Here are some real-world scenarios using filter chains:
{
"user": {
"name": " sarah CHEN ",
"signup_date": "2024-01-15T09:00:00Z"
},
"product": {
"name": "Super Widget Pro",
"price": 99.99,
"discount": 0.15
}
}Clean name: {{ user.name | strip | downcase | capitalize }}
Member since: {{ user.signup_date | date: "%B %Y" }}
Final price: ${{ product.price | times: 0.85 | round: 2 }}
Save: ${{ product.price | times: product.discount | round: 2 }}
URL slug: {{ product.name | downcase | replace: " ", "-" | remove: "-pro" }}Clean name: Sarah chen
Member since: January 2024
Final price: $84.99
Save: $15.00
URL slug: super-widgetBest practices for using filters
As you work with filters, make sure to keep these best practices in mind.
Order matters in filter chains
Put filters in logical sequence. For example, always strip_html before truncate:
<!-- Good: Strip HTML first, then truncate -->
{{ content | strip_html | truncate: 100 }}
<!-- Bad: Might truncate in middle of HTML tag -->
{{ content | truncate: 100 | strip_html }}Use the default filter defensively
Protect against missing data by providing sensible defaults:
Welcome, {{ user.name | default: "valued customer" }}!Format numbers for readability
Always round currency and percentages to appropriate precision:
Total: ${{ amount | round: 2 }}
Conversion: {{ rate | times: 100 | round: 1 }}%Keep filter chains readable
For complex transformations, consider breaking across lines or using intermediate variables (which you'll learn about in the Tags chapter):
{% assign clean_content = article.content | strip_html %}
{% assign preview = clean_content | truncate: 200 %}
{{ preview }}Filters are essential tools in your Liquid toolkit. They let you transform data on the fly, handle missing values gracefully, and format output precisely for each notification channel. Master these patterns, and you'll create templates that are both powerful and maintainable.