Liquid syntax list
This page contains a list of the liquid tags, keys, and filters available to you in Customer.io. If you're new to liquid, you can learn more in our guide about personalizing messages.
📌 You're looking at the latest Liquid documentation
If your account was created on or after Nov 28, 2023, you are using our latest liquid version for all messages. If your account was created before this date, go to How to upgrade your liquid version for more info.
The two versions are largely similar, but you'll find a list of differences on our Liquid Upgrade page.
📌 You're looking at legacy Liquid documentation
If your account was created on or after Nov 28, 2023, you are using our latest liquid version for all messages. If your account was created before this date, go to How to upgrade your liquid version for more info.
The two versions are largely similar, but you'll find a list of differences on our Liquid Upgrade page.
Customer.io Keys
cio_link
mailto links. If you use our SDKs, you do not need to use this tag to track links in in-app messages. To track links in emails, go to cio_link_id below.The filters track and url_params are optional. If you exclude these filters, url parameters will be present and tracking will be on. To turn either off, set them to false. For more info on this tag, go to Link tracking.
Do not use this tag to track deep links.
{% cio_link url:https://example.com %}
{% cio_link url:https://example.com track:true url_params:true %}
{% cio_link url:https://example.com track:true url_params:false %}
{% cio_link url:https://example.com track:false url_params:true %}
{% cio_link url:https://example.com track:false url_params:false %} https://e.customeriomail.com/e/c/{string}
https://e.customeriomail.com/e/c/{string}
https://e.customeriomail.com/e/c/{string}
https://example.com?utm_campaign={string}&utm_content={string}&utm_medium={string}&utm_source=customer.io
https://example.com cio_link_id
For links in non-email messages, go to cio_link above.
<a href="https://yourwebsite.com/confirm?link_id={% cio_link_id %}" class="untracked">Text</a> customer attributes
customer scope. You may want to use customer attributes with an if conditional so you have text to fallback to if a customer doesn't have the attribute in question. You can use default rather than checking for empty strings using == blank or != blank.{{customer.<attribute_name>}} Hi {{ customer.first_name | default: "there" }}
{% if customer.first_name != blank %}
Hello {{ customer.first_name }}!
{% else %}
Hello there!
{% endif %} event properties
event scope. You may want to use event properties with an if conditional, so that you have text to fallback to if an event doesn't have the property in question or your property doesn't contain the value you expect. You can use the default filter rather than checking for empty strings using == blank or != blank too.{{event.<property>}} {% if event.type == "purchase" %}
Thanks for your purchase!
{% else %}
Thanks for using our service!
{%endif%} event_id
{{event_id}} event_name
{{event_name}} event_timestamp
{{event_timestamp}} journey attributes
journey object.{{journey.<attribute_name>}} {% if journey.weather != blank %}
Here's the forecast for the day: {{journey.weather}}!
{% else %}
Check out your forecast online at...
{%endif%} object & relationship attributes
{{objects.<object-type-name>[#].<object-attribute-name>}} // reference an object attribute
{{objects.<object-type-name>[#].relationship.<relationship-attribute-name>}} // reference a relationship attribute
{{customer._relationship.<relationship-attribute-name>}} // reference a relationship attribute for the audience member of object or relationship-triggered campaigns // list all online classes that a person has not started
{% for class in objects.online_classes %}
{% if class.relationship.status == "not_started" %}
- {{class.name}}
{% endif %}
{% endfor %} render_liquid
render_liquid, liquid syntax in the attribute value displays as static text instead of rendering dynamically.For example, if an LLM action stores Hello {{customer.first_name}} in a journey attribute called body, referencing it with {{journey.body}} outputs the literal text Hello {{customer.first_name}}. Use {% render_liquid journey.body %} to render the customer's actual name.
{% render_liquid <liquid-key-name>.<attribute_name> %} {% render_liquid journey.body %} snippets
{{snippets.footer}} trigger properties
trigger object can pull in data that triggers a transactional message, API-triggered broadcast, and campaigns triggered by webhooks, objects, or relationships. Remember to add fallbacks with conditionals or the default filter; otherwise, your messages could fail to send if the value and a fallback don't exist. Learn more about using trigger objects.// For transactional messages, webhook-triggered campaigns, or API-triggered broadcasts
{{trigger.<data.property>}}
// For object-triggered campaigns
{{trigger.<object_type>.<attribute_name>}}
// For object or relationship-triggered campaigns
{{trigger.relationship.<attribute_name>}} {% if trigger.first_name %}
Hi {{trigger.first_name | capitalize}}!
{% else %}
Hi friend!
{%endif%} view_in_browser_url
https://e.customeriomail.com/deliveries/....{% view_in_browser_url %} Customer.io Unsubscribe Keys
manage_subscription_preferences_url
{% manage_subscription_preferences_url %} tracking_consent_url
{% tracking_consent_url %} unsubscribe
{% unsubscribe %} unsubscribe_url
{% unsubscribe_url %} Customer.io Meta Keys
.id values are useful as UTM parameters in links so you can log where your traffic is coming from or attribute customer actions to messages.campaign.id
For example, the campaign ID here is 2000: https://fly.customer.io/env/12345/v2/campaigns/2000/overview.
And here it's 1: https://fly.customer.io/env/109950/composer/newsletters/1/templates/21."
{{campaign.id}} campaign.name
{{campaign.name}} campaign.subscription_topic_ids
{{campaign.subscription_topic_ids}} campaign.type
This returns the type of trigger for a campaign: behavioral (legacy segment-triggered), seg_attr (attribute or segment-triggered), transactional (event-triggered), form, date, object, or relationship.
For messages sent through our Transactional API, this returns transactional_message.
It also returns triggered_broadcast for an API-triggered broadcast or newsletter accordingly."
{{campaign.type}} content
{{content}} delivery_id
unsent. This is generated when the message is drafted or sent.{{delivery_id}} editor
bee (drag-and-drop email editor), html (code email editor), wysiwyg (rich text email editor), or rich (rich push editor). For Create or update person actions, in-app messages, Design Studio emails, SMS, and custom push, this value is blank.{{editor}} layout.id
{{layout.id}} layout.name
{{layout.name}} message.id
{{message.id}} of 200. Note that this identifies the action in your workflow, not the individual delivery instances. Every SMS delivery generated from the action would have a different {{delivery_id}}.For newsletters, the message.id is the value after templates in your URL. For example, the message.id here is 21 https://fly.customer.io/env/109950/composer/newsletters/1/templates/21.
{{message.id}} message.journey_id
journey.id value sent in our Reporting Webhooks.{{message.journey_id}} message.name
{{message.name}} message.preheader
{{message.preheader}} message.send_to_unsubs
{{message.send_to_unsubs}} message.subject
{{message.subject}} message.subscription_topic_ids
{{message.subscription_topic_ids}} message.subscription_topic.name
{{message.subscription_topic.name}}
{{message.subscription_topic.name | default: "Unsubscribe"}} message.type
email_action, delay_seconds_action, delay_time_window_action, split_randomized_action, webhook_action, twilio_action, slack_action, attribute_update_action, filter_match_delay_action, grace_period_action, push_action, conditional_wait_action, conditional_branch_action, multi_split_branch_action, random_cohort_branch_action, exit_action, static_seg_update_action, collection_query_action, create_event_action, multi_lang_branch_action, batch_update_action, in_app_action.{{message.type}} subscription_topic_name
lang='pt'. If the language doesn't match a translation in your subscription center, customers will see the default language.{% subscription_topic_name %}
{% subscription_topic_name lang='pt' %} Variable Tags
assign
{% assign var_name = 'value' %} {% assign favorite_food = 'apples' %} {{ favorite_food }} capture
{% capture about_me %}I am 28 and my favorite food is pasta.{% endcapture %} {{ about_me }} Iterative Tags
cycle
<ul>{% assign characters = "coyote,bugs,tweety" | split: "," %}
{% for character in characters %}
<li class="{% cycle 'odd', 'even' %}">{{ character }}</li>
{% endfor %}
</ul> <ul>
<li class='odd'>coyote</li>
<li class='even'>bugs</li>
<li class='odd'>tweety</li>
</ul> for loop
{% for item in array %}
{{ item }}
{% endfor %}
{% comment %} You can use a break tag so the loop stops iterating. {% endcomment %}
{% for i in (1..5) %}
{% if i == 4 %}
{% break %}
{% else %}
{{ i }}
{% endif %}
{% endfor %} {% comment %} You can output each item of the array. {% endcomment %}
{% for member in members_of_band %}
{{member}}
{% endfor %}
{% comment %} If the items are objects, you can output properties from each object. {% endcomment %}
{% for product in event.products %}
- {{ product.title }} x {{ product.price }}
{% endfor %} Conditional Tags
case
For example, you might use this to display different text depending on if a customer lives in a specific country.
{% case condition %}
{% when "value1" %}
text when condition is value1.
{% when "value2" or "value3" %}
text when condition is value2 or value3
{% else %}
text when condition does not match other conditions
{% endcase %} if
elsif to add multiple 'if' conditions and else for the block of code you want to execute if all conditions are false. Use the default filter to specify a fallback for when a variable does not exist instead of an if statement. Find more information about conditional liquid here.{% if customer.lastEventType == "sports" %}
You last attended a sports event, so we thought you might like to try out our leagues! Fill out our interest form below.
{% elsif customer.lastEventType == "theater" %}
You attended a theater event, so we thought you might like to try out our after show parties! Fill out our interest form below.
{% elsif customer.lastEventType %}
{% comment %} If the attribute exists and does not equal sports or theater, then this will render.{% endcomment %}
You last attended {{customer.lastEventType}}; we'd love to hear what other offerings you'd like from us in the form below.
{% else %}
{% comment %} If the attribute does not exist, this will render. {% endcomment %}
Let us know your interests in the form below so we can better serve you!
{% endif %} unless
{% unless product.name == "cool beans" %}
The beans are not cool.
{% endunless %} Logical Operators
and and or operators to combine logic statements to evaluate multiple conditions.and
{% if condition1 and condition2 %}
// do something if both condition1 and condition 2 are true
{% endif %} {% if customer.name == "bugs bunny" and event.episode_start == true %}
What's up doc?
{% else %}
That's all folks!
{% endif %} does not equal (!=)
!= to check that two values are not equal to each other.{% if customer.name != "daffy duck" %}
Duck season!
{% else %}
Wabbit season!
{%endif%} equals (==)
== to check if two values are equal to each other.{% if customer.name == "daffy duck" %}
Wabbit season!
{% else %}
Duck season!
{% endif %} greater than and greater than or equal to (>, >=)
> to match when one value is greater than another. Use >= to match when one value is greater than or equal to another.{% if val1 > val2 %}
{% comment %}do something if val1 is greater than val2{% endcomment %}
{% endif %} {% if customer.acct_age_years > 1 %}
Thanks for being with us these past years
{% else %}
Thanks for spending the last year with us!
{% endif %} less than and less than or equal to (<, <=)
< to match when one value is less than another. Use <= to match when one value is less than or equal to another.{% if val1 < val2 %}
{% comment %}do something if val1 is less than val2{% endcomment %}
{% endif %} {% if customer.purchases < 5 %}
Thanks for your support
{% else %}
Thanks for spending the last year with us!
{% endif %} or
{% if condition1 or condition2 %}
{% comment %}do something if either condition1 and condition 2 are true{% endcomment %}
{% endif %} {% if customer.name == "bugs bunny" or customer.group == "looney toons" %}
That's all folks!
{% else %}
See you later!
{% endif %} Timestamps and Dates
add_day
{{ <unix_timestamp> | add_day: <int_days> }} {{ 1477430251 | add_day: 7 }} add_month
{{ <unix_timestamp> | add_month: <int_months> }} {{ 1477430251 | add_month: 7 }} add_year
{{ <unix_timestamp> | add_year: <int_years> }} {{ 1477430251 | add_year: 4 }} countdown
The countdown timer cannot contain more than 60 frames. This limits the size of the animated GIF in your messages. So, if the resolution is set to seconds, the counter will stop after 60 seconds from when the person opens their message. The countdown image reloads when a person opens the message again, so the counter will always be relevant to the user's current time, but it cannot count indefinitely.
| Parameter | required | format | default | description |
| :--- | :--: | :--: | :--- | :--- |
| point | ✓ | integer | | The font size for the timer |
| time | ✓ | ISO 8601 timestamp | | The date and time you want to countdown to in the format YYYY-MM-DD hh:mm:ss (GMT). Remember to close the time in quotes, as the value includes a space. This field does not accept liquid variables. |
| fg | ✓ | hex color | | The foreground (font) hexidecimal color |
| bg | ✓ | hex color | | The background hexidecimal color |
| apng | | boolean | false | Determines whether to show your countdown as a gif (default) or animated PNG. Note that some browsers/email clients don't support apng images. |
| font | | string | inter, roboto | The font family for your timer |
| weight | | string | normal | The font weight, takes normal CSS font-weight values. |
| locale | | language code | en | The language you want to display: en (English), ru (Russian), jp (Japanese), zh (Chinese), pt (Portugese), es (Spanish), and fr (French) |
| looping | | boolean | false | Determines whether the countdown timer should restart after it finishes |
| resolution | | one of S, M, H, D | S | Determines how often the timer counts down—by the second, minute, hour, or day. |
| frames | | integer | 1 | Number of seconds you want to show, based on the resolution, where seconds: 60, minutes: 2, hours: 1, days: 1 |
{% countdown point:64 font:roboto weight:light fg:000000 bg:f2f6f9 time:"2022-07-04 12:00:00 (GMT)" locale:en looping:true resolution:S frames:2 %}
date
{{ 1483272000 | date: '%H:%M, %a, %b %d, %Y' }}
{{ 1483272000 | date: '%a., %-m/%d at %I:%M %P %Z' }}
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "Asia/Colombo" }}
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", 360 }} 12:00, Sun, Jan 01, 2017
Sun., 1/01 at 12:00 pm UTC
1991-01-01T04:30:00
1990-12-31T17:00:00 date_to_long_string
{{ site.time | date_to_long_string }}
{{ site.time | date_to_long_string: "ordinal" }}
{{ site.time | date_to_long_string: "ordinal", "US" }} 07 November 2008
7th November 2008
November 7th, 2008 date_to_rfc822
{{ site.time | date_to_rfc822 }} Mon, 07 Nov 2008 13:07:54 -0800 date_to_string
{{ site.time | date_to_string }}
{{ site.time | date_to_string: "ordinal" }}
{{ site.time | date_to_string: "ordinal", "US" }} 07 Nov 2008
07th Nov 2008
Nov 7th, 2008 date_to_xmlschema
{{ site.time | date_to_xmlschema }} 2008-11-07T13:07:54-08:00 event_timestamp
now tag! This throws an error if the event has not been sent recently (within the last ~30 days).{{event_timestamp}} now
date.To modify date or time with add or subtract filters you must convert now into a unix timestamp first using date: '%s'. If you use our built in add_day, add_month, or add_year filters, you must convert the timestamp to an integer first. You can do this by using the plus filter to add 0 as shown in the second example below.
{{ 'now' | date: '%I:%M %p %B %d, %Y' }}
{{ 'now' | date: '%s' | plus: 0 | add_day: 1 | date: '%I:%M %p %B %d, %Y'}} 08:28 AM May 11, 2021
08:28 AM May 12, 2021 subtract_day
{{ <unix_timestamp> | subtract_day: <int_days> }} {{ 1477430251 | subtract_day: 7 }} subtract_month
{{ <unix_timestamp> | subtract_month: <int_months> }} {{ 1477430251 | subtract_month: 2 }} subtract_year
{{ <unix_timestamp> | subtract_year: <int_years> }} {{ 1477430251 | subtract_year: 4 }} Array Filters
for loop or grab items at a particular index of the array, to display information for your audience.compact
nil (empty) values from an array.{{ "mick, keith, nil, Charlie" | compact }} mick, keith, Charlie concat
concat does not remove duplicate entries unless you also use the uniq filter.{% assign stones = "mick, keith, ronnie, charlie" | split: ", " %}
{% assign beatles = "john, paul, george, ringo" | split: ", " %}
{% assign rolling_beatles = stones | concat: beatles %}
{{ rolling_beatles | join: ", " }} mick, keith, ronnie, charlie, john, paul, george, ringo find
{{ customer.purchases | find: "type", "kitchen" | json }} {"date":"1726589206","title":"utensils","type":"kitchen"} find_exp
{{ members | find_exp: "item", "item.graduation_year == 2014" | json }} {"graduation_year":2014,"name":"John"} first
acme.characters = ["Wile E Coyote", "Road Runner"]
{{ acme.characters | first }} Wile E Coyote group_by
{% assign groups = customer.purchases | group_by: "type" %}
{% for group in groups %}
{{group.name | capitalize}}
{% for item in group.items %}
- {{ item.title }}
{% endfor %}
{% endfor %} Bathroom
- shower curtain
- body soap
Kitchen
- forks
- spoons
- knives group_by_exp
{% assign groups = customer.purchases | group_by_exp: "item", "item.type contains 'kitchen'" %}
{% for group in groups %}
{% if group.name == true %}
You bought some kitchen supplies from us in the past year:
{% for item in group.items %}
- {{item.title}}
{% endfor %}
{% endif %}
{% endfor %} You bought some kitchen supplies from us in the past year:
- forks
- spoons
- knives join
acme.characters = ["Wile E Coyote", "Road Runner"]
{{ acme.characters | join: ', ' }} Wile E Coyote, Road Runner json_array_uniq
to_json if a string is the desired output.{{ customer.arrayOfColorObjects | concat: customer.arrayOfColorObjectsWithDuplicationsAndNew | json_array_uniq: 'name' | to_json }} [{"color":"brown","name":"coyote"},{"color":"black","name":"bugs"},{"color":"yellow","name":"tweety"},{"color":"black","name":"daffy"}] last
acme.characters = ["Wile E Coyote", "Road Runner"]
{{ acme.characters | last }} Road Runner limit
{% assign beatles = "john, paul, george, ringo" | split: ", " %}
{{ beatles | limit: 2 | join: ", " }} john, paul map
Array of objects: [{"name":"coyote"},{"name":"bugs"},{"name":"tweety"}]"
{% assign names = customer.characters | map: 'name' %} coyote, bugs, tweety pop
{% assign fruits = "apples, oranges, peaches" | split: ", " %}
{% assign everything = fruits | pop %}
{% for item in everything %}
- {{ item }}
{% endfor %} - apples
- oranges push
{% assign fruits = "apples, oranges" | split: ", " %}
{% assign everything = fruits | push: "peaches" %}
{% for item in everything %}
- {{ item }}
{% endfor %} - apples
- oranges
- peaches remove
{% assign pl = customer.products | remove: customer.products[0] %}
- {{ customer.products.size }}
- {{ pl.size }} - 2
- 1 reverse
{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}
{{ my_array | reverse | join: ", " }} plums, peaches, oranges, apples shift
{% assign fruits = "apples, oranges, peaches" | split: ", " %}
{% assign everything = fruits | shift %}
{% for item in everything %}
- {{ item }}
{% endfor %} - oranges
- peaches size
{{ "That's all, folks!" | size }}
{{ customer.latest_purchase | size }}
{{ objects.online_classes | size }}
{{ objects.online_classes.size }} 18 // The number of characters
4 // If `latest_purchase` is an array, this returns the number of items in the array. Otherwise, it returns a count of characters.
2 // The number of objects (onlines classes) that a person is related to.
2 // Using the size filter with dot notation sort
{% assign beatles = "paul, john, ringo, george" | split: ", " %}
{{ beatles | sort | join: ", " }} george, john, paul, ringo sort_natural
{{ "mick, keith, Charlie, Ronnie" | sort_natural }} Charlie, keith, mick, Ronnie sum
sum filter aggregates numbers. Every value is cast to a number. Unlike with legacy liquid, sum does not concatenate numbers, strings, or booleans. You can specify an object property to sum, as shown in the third example below.{% assign nums = '1,2,3' | split: ',' %}
{{ nums | sum }}
{% assign letters = 'a,b,c' | split: ',' %}
{{ letters | sum }}
{{ cart.products | sum: 'total_number' }} {% comment %} where `total_number` includes milk,cheese,eggs {% endcomment %}
{{ purchase.products | sum }} {% comment %} where `products` includes true,false {% endcomment %} 6
0
3
1 {% comment %} counts the number of trues, would also aggregate numbers alongside booleans {% endcomment %} uniq
{% assign my_array = '"lions", "tigers", "bears", "bears", "lions"' %}
{{ my_array | uniq | join: ", " }} lions, tigers, bears unshift
{% assign fruits = "oranges, peaches" | split: ", " %}
{% assign everything = fruits | unshift: "apples" %}
{% for item in everything %}
- {{ item }}
{% endfor %} - apples
- oranges
- peaches where
All Players:
{% for player in customer.players %}
- {{ player.last_name }}
{% endfor %}
Baseball Players:
{% assign baseball_players = customer.players | where: "sport", "baseball" %}
{% for player in baseball_players %}
- {{ player.last_name }}
{% endfor %}
----------------------------
All products:
{% for product in customer.products %}
- {{ product.title }}
{% endfor %}
{% assign available_products = customer.products | where: "available" %}
Available products:
{% for product in available_products %}
- {{ product.title }}
{% endfor %} where_exp
All products:
{% for product in customer.products %}
- {{ product.title }}
{% endfor %}
{% assign kitchen_products = customer.products | where_exp: "item", "item.size > 30 and item.type == 'kitchen'" %}
Kitchen products:
{% for product in kitchen_products %}
- {{ product.title }}
{% endfor %} where_not
where_not, you provide two items separated by a comma: the property you want to match on and the value you want to match.All players:
{% for player in customer.players %}
- {{ player.last_name }}
{% endfor %}
Not baseball players:
{% assign not_baseball_players = customer.players | where_not: "sport", "baseball" %}
{% for player in not_baseball_players %}
- {{ player.last_name }}
{% endfor %} All players:
- Posey
- Maradona
- Montana
- Gretzky
- Jordan
Not baseball players:
- Maradona
- Montana
- Gretzky
- Jordan Number and Currency Filters
Some tags, like the currency and format_number, take an optional localization parameter, formatting the output for a specific locale. These tags use the format {{ 10 | currency: "en-us" }}, which would output $10.00.
A list of locales and currency codes
af, ar, az, be, bg, bn, bs, ca, cs, cy, da, de-AT, de-CH, de-DE, de, dz, el-CY, el, en-AU, en-CA, en-CY,
en-GB, en-IE, en-IN, en-NZ, en-TT, en-US, en-ZA, en, eo, es-419, es-AR, es-CL, es-CO, es-CR, es-EC, es-ES,
es-MX, es-NI, es-PA, es-PE, es-US, es-VE, es, et, eu, fa, fi, fr-CA, fr-CH, fr-FR, fr, gl, gsw-CH, he,
hi-IN, hi, hr, hu, id, is, it-CH, it, ja-JP, ja, ka, kk, km, kn, ko, lb, lo, lt, lv, mg, mk, ml, mn, mr-IN,
ms, na, nb, ne, ng, nl, nn, oc, or, pa, pl, pt-BR, pt-MZ, pt, rm, ro, ru, sc, sd, sk, sl, sn, sq, sr, st, sv-FI,
sv-SE, sv, sw, ta, te, th, tl, tn, tr, tt, ug, uk, ur, uz, vi, wo, za, zh-CN, zh-HK, zh-Hant-MO, zh-MO,
zh-TW, ao, cd, ci, cm, eg, gh, ke, ls, ly, ma, mu, mw, mz, sz, tz, zm
We support the following currency codes:
'AED','AFN','ALL','AMD','ANG','AOA','ARS','AUD','AWG','AZN','BAM','BBD','BDT','BGN','BHD','BIF','BMD',
'BND','BOB','BRL','BSD','BTN','BWP','BYN','BZD','CAD','CDF','CHF','CLP','CNY','COP','CRC','CUC','CUP',
'CVE','CZK','DJF','DKK','DOP','DZD','EGP','ERN','ETB','EUR','FJD','FKP','GBP','GEL','GHS','GIP','GMD',
'GNF','GTQ','GYD','HKD','HNL','HRK','HTG','HUF','IDR','ILS','INR','IQD','IRR','ISK','JMD','JOD','JPY',
'KES','KGS','KHR','KMF','KPW','KRW','KWD','KYD','KZT','LAK','LBP','LKR','LRD','LSL','LYD','MAD','MDL',
'MGA','MKD','MMK','MNT','MOP','MRU','MUR','MVR','MWK','MXN','MYR','MZN','NAD','NGN','NIO','NOK','NPR',
'NZD','OMR','PAB','PEN','PGK','PHP','PKR','PLN','PYG','QAR','RON','RSD','RUB','RWF','SAR','SBD','SCR',
'SDG','SEK','SGD','SHP','SLE','SLL','SOS','SRD','SSP','STN','SVC','SYP','SZL','THB','TJS','TMT','TND',
'TOP','TRY','TTD','TWD','TZS','UAH','UGX','USD','UYU','UZS','VES','VND','VUV','WST','XAF','XCD','XDR',
'XOF','XPF','XSU','YER','ZAR','ZMW','ZWL'
currency
{% comment %} no arguments: {% endcomment %}
{{ 1234567.896 | currency }}
{% comment %} only locale: {% endcomment %}
{{ 1234567.896 | currency: 'en-GB' }}
{% comment %} locale and currency code: {% endcomment %}
{{ 1234567.896 | currency: 'en', 'EUR' }} $1,234,567.90
£1,234,567.90
€1,234,567.90 format_number
NOTE: This replaces the former number_with_delimeter filter.
{{ 10000 | format_number }}
{{ 123456.78 | format_number: "fr" }} 10,000
123 456,78 round
{{ 4.32 | round }}
{{ 4.32 | round: 1 }} 4
4.3 rounded_currency
{% comment %} no arguments: {% endcomment %}
{{ 1234567.896 | rounded_currency }}
{% comment %} only locale: {% endcomment %}
{{ 1234567.896 | rounded_currency: 'en-GB' }}
{% comment %} locale and currency code: {% endcomment %}
{{ 1234567.896 | rounded_currency: 'en', 'EUR' }} $1,234,568
£1,234,568
€1,234,568 Math Filters
divided_by
{{ 10 | divided_by: 2.5 }}
{{ 10 | divided_by: 4 }}
{{ 10 | divided_by: 4.0 }} 4
2.5
2.5 modulo
{{ 3 | modulo: 2 }} 1 times
{{ 5 | times: 2 }}
{{ 10 | times: 2.5 }} 10
25 String Filters
append
{{ "What's all the hubbub, " | append: "bub?" }} What's all the hubbub, bub? array_to_sentence_string
split filter.{{ customer.groceries | split:"," | array_to_sentence_string }}
{{ customer.groceries | split:"," | array_to_sentence_string: "or" }} cherry, kiwi, and passion fruit
cherry, kiwi, or passion fruit base64_decode
{{ "Zm9vLmJhcg==" | base64_decode }} foo.bar base64_url_safe_decode
{{ "Zm9vLmJhcg" | base64_url_safe_decode }} foo base64_url_safe_encode
- and _ in place of + and /.{{ "foo" | base64_url_safe_encode }} Zm9vLmJhcg capitalize
{{ "hello world" | capitalize }} Hello world cgi_escape
{{ "overview: account" | cgi_escape }} overview%3A+account contains
{% if product.description contains 'lorem ipsum' %}
You might also be interested in Fillerama or Office Ipsum.
{% endif %} downcase
{{ 'STRING' | downcase }} {{ "ACME" | downcase }} acme escape
url_encode instead.{{ "win+help@customer.io" | escape }} win%2Bhelp%40customer.io escape_once
{{ "1 < 2 & 3" | escape_once }} 1 < 2 & 3 hex_base64
hmac_sha256 filter.{{ "Customer.io" | hmac_sha256: "some_key" | hex_base64 }} bd23cyOCFrzicxM7w/ahKoJPQd0YTQlFLwXHZZ2ufVc= hmac_sha1
{{ "Customer.io" | hmac_sha1: "some_key" }} 2bdf556c9a75766f258d1e2824f6d0e31d1beedc hmac_sha256
{{ "Customer.io" | hmac_sha256: "some_key" }} 6dddb773238216bce273133bc3f6a12a824f41dd184d09452f05c7659dae7d57 lstrip
text{{ " Customer.io " | lstrip }}text textCustomer.io text md5
{{ "Customer.io" | md5 }} d52b6a207bf5255c05b1d0056230617e newline_to_br
<br />
Customer.io<br />
liquid<br /> normalize_whitespace
{{ "a \n b" | normalize_whitespace }} a b number_of_words
{{ "Welcome to Customer.io!" | number_of_words }} 3 pluralize
{{ int-val | pluralize: 'singular', 'plural'}} {{ event.item_count | pluralize: 'item', 'items' }} 3 items prepend
{{ "Sufferin' succotash!" | prepend: "Sylvester: " }} Sylvester: Sufferin' succotash! remove_first
{{ "folks that's all, folks!" | remove_first: "folks" }} that's all folks! remove_last
{{ "foobarbar" | remove_last: "bar" }} foobar remove
{{ "And that's all, folks!" | remove: ", folks" }} And that's all! replace
{{ "String you want to replace values in" | replace: "find-str", "replace-str" }} {{ "Coyotes never catch roadrunners!" | replace: "never", "always" }} Coyotes always catch roadrunners! replace_first
{{ "String you want to replace values in" | replace_first: "find-str", "replace-str" }} {{ "roller rocket roller skates" | replace_first: "roller", "awesome" }} awesome rocket roller skates replace_last
{{ "foobarbar" | replace_last: "bar", "foo" }} foobarfoo rstrip
text{{ " Customer.io " | rstrip }}text text Customer.iotext sha1
{{ "Customer.io" | sha1 }} c197ff0ae0a41983362f35ca972c544061c54d4c sha256
{{ "Customer.io" | sha256 }} 6dddb773238216bce273133bc3f6a12a824f41dd184d09452f05c7659dae7d57 slice
If the first argument is a negative number, the index is begins from the end of the string.
{{ "string" | slice: <req, index of char>, <optional, length of result> }} {{ "Customer.io" | slice: 3 }}
{{ "Customer.io" | slice: 3, 3 }}
{{ "Customer.io" | slice: '-4', 3 }} t
tom
r.i slugify
true if you want to retain the original casing of the string. By default, the slugify filter replaces spaces and non-alphanumeric characters with dashes and lowercases all letters.| mode | replaces |
| :--- | :--- |
| "none" | no characters |
| "raw" | spaces |
| "default" | spaces and non-alphanumeric characters |
| "pretty" | spaces and non-alphanumeric characters except for ._~!$&'()+,;=@ |
| "ascii" | spaces, non-alphanumeric, and non-ASCII characters |
| "latin" | like default, except Latin characters are first transliterated (e.g. àèïòü to aeiou) |
{{ "The _config.yml file" | slugify }}
{{ "The _config.yml file" | slugify: "pretty" }}
{{ "The _cönfig.yml file" | slugify: "ascii" }}
{{ "The cönfig.yml file" | slugify: "latin" }}
{{ "The cönfig.yml file" | slugify: "latin", true }} the-config-yml-file
the-_config.yml-file
the-c-nfig-yml-file
the-config-yml-file
The-config-yml-file split
{% assign rolling_stones = "Mick, Keith, Ronnie, Charlie" | split: ", " %}
{% for member in rolling_stones %}
{{ member }}
{% endfor %} strip
text{{ " Customer.io " | strip }}text Customer.io strip_html
{{ "Eh, what's <i>up</i>, <b>Doc</b>?" | strip_html }} Eh, what's up, Doc? strip_newlines
{{ product.description | strip_newlines }} titlecase
{{ 'string' | titlecase }} {{ "rocket roller skates" | titlecase }} Rocket Roller Skates truncate
{{ "I knew I shoulda taken that left turn at Albuquerque." | truncate: 20 }} I knew I shoulda ... truncatewords
{{ "I knew I shoulda taken that left turn at Albuquerque." | truncatewords: 8 }} I knew I shoulda taken that left turn... upcase
{{ 'string' | upcase }} {{ 'acme' | upcase }} ACME uri_escape
{{ "https://example.com/?q=foo, \bar?" | uri_escape }} https://example.com/?q=foo,%20%08ar? url_decode
url_encode.{{ "%27Customer.io+is+great%27" | url_decode }} Customer.io is great url_encode
{{ "cool.person@example.com" | url_encode }} cool.person%40example.com xml_escape
{{ "Have you seen \'Learn the basics: video guide\'?" | xml_escape }} Have you read 'James & the Giant Peach'? Miscellaneous
comment
{% comment %} Don't display me! {% endcomment %} default
default filter rather than checking for empty strings using == blank or != blank.{{ product_color | default: "red" }}
{{ product_price | default: 2.99 }} from_json
from_json parses string-encoded (or 'stringified') JSON so you can reference its values with liquid. Note that you don't need this filter for the JSON-encoded values of people, events, or objects; they are already automatically parsed.{% assign var = '{"key": "value", "number": 123, "boolean": true}' | from_json %}
{{ var.key }}
{{ var.number }}
{{ var.boolean }} {% assign fruit = '{"type": "kiwi", "quantity": 2, "sweet": true}' | from_json %}
{{ fruit.type }}
{{ fruit.quantity }}
{{ fruit.sweet }}
{% assign greeting = '[{"greeting": "hello" }, {"greeting": "hey" }, {"greeting": "hi" }, {"greeting": "howdy" }]' | from_json %}
{{ intro[0].greeting }}
{{ intro[1].greeting }}
{{ intro[2].greeting }}
{{ intro[3].greeting }} kiwi
2
true
hello
hey
hi
howdy json
jsonify). An additional space parameter can be specified to format/prettify the JSON.{% assign arr = "foo bar coo" | split: " " %}
{{ arr | json: 4 }} [
"foo",
"bar",
"coo"
] raw
{% raw %}
{{This}} is displayed exactly as typed.
{% endraw %} to_json
{{ customer | to_json }} sends all your customer data into a JSON variable.{{ customer | to_json }} whitespace control
{% assign username = "Charlie" %}
Hello, {{ username -}} ! Hello, Charlie! Customer.io Keys
cio_link
mailto links. If you use our SDKs, you do not need to use this tag to track links in in-app messages. To track links in emails, go to cio_link_id below.The filters track and url_params are optional. If you exclude these filters, url parameters will be present and tracking will be on. To turn either off, set them to false. For more info on this tag, go to Link tracking.
Do not use this tag to track deep links.
{% cio_link url:https://example.com %}
{% cio_link url:https://example.com track:true url_params:true %}
{% cio_link url:https://example.com track:true url_params:false %}
{% cio_link url:https://example.com track:false url_params:true %}
{% cio_link url:https://example.com track:false url_params:false %} https://e.customeriomail.com/e/c/{string}
https://e.customeriomail.com/e/c/{string}
https://e.customeriomail.com/e/c/{string}
https://example.com?utm_campaign={string}&utm_content={string}&utm_medium={string}&utm_source=customer.io
https://example.com cio_link_id
For links in non-email messages, go to cio_link above.
<a href="https://yourwebsite.com/confirm?link_id={% cio_link_id %}" class="untracked">Text</a> customer attributes
customer scope. You may want to use customer attributes with an if conditional, so that you have text to fallback to if a customer doesn't have the attribute in question.{{customer.<attribute_name>}} {% if customer.name != blank %}
Hi {{customer.name | capitalize}}
{% else %}
Hi Buddy
{%endif%} event properties
event scope. You may want to use event properties with an if conditional, so that you have text to fallback to if an event doesn't have the property in question or your property doesn't contain the value you expect.{{event.<property>}} {% if event.type == "purchase" %}
Thanks for your purchase!
{% else %}
Thanks for using our service!
{%endif%} event_id
{{event_id}} event_name
{{event_name}} event_timestamp
{{event_timestamp}} journey attributes
journey object.{{journey.<attribute_name>}} {% if journey.weather != blank %}
Here's the forecast for the day: {{journey.weather}}!
{% else %}
Check out your forecast online at...
{%endif%} object & relationship attributes
{{objects.<object-type-name>[#].<object-attribute-name>}} // reference an object attribute
{{objects.<object-type-name>[#].relationship.<relationship-attribute-name>}} // reference a relationship attribute
{{customer._relationship.<relationship-attribute-name>}} // reference a relationship attribute for the audience member of object or relationship-triggered campaigns // list all online classes that a person has not started
{% for class in objects.online_classes %}
{% if class.relationship.status == "not_started" %}
- {{class.name}}
{% endif %}
{% endfor %} snippets
{{snippets.footer}} trigger properties
trigger object pulls in data that triggers a transactional message, API-triggered broadcast, and campaigns triggered by webhooks, objects, or relationships. Remember to add fallbacks with conditionals; otherwise, your messages could fail to send if the value and a fallback don't exist. Learn more about using trigger objects.// For transactional messages, webhook-triggered campaigns, or API-triggered broadcasts
{{trigger.<data.property>}}
// For object-triggered campaigns
{{trigger.<object_type>.<attribute_name>}}
// For object or relationship-triggered campaigns
{{trigger.relationship.<attribute_name>}} {% if trigger.first_name %}
Hi {{trigger.first_name | capitalize}}!
{% else %}
Hi friend!
{%endif%} view_in_browser_url
https://e.customeriomail.com/deliveries/....{% view_in_browser_url %} Customer.io Unsubscribe Keys
manage_subscription_preferences_url
{% manage_subscription_preferences_url %} tracking_consent_url
{% tracking_consent_url %} unsubscribe
{% unsubscribe %} unsubscribe_url
{% unsubscribe_url %} Customer.io Meta Keys
.id values are useful as UTM parameters in links so you can log where your traffic is coming from or attribute customer actions to messages.campaign.id
For example, the campaign ID here is 2000: https://fly.customer.io/env/12345/v2/campaigns/2000/overview.
And here it's 1: https://fly.customer.io/env/109950/composer/newsletters/1/templates/21."
{{campaign.id}} campaign.name
{{campaign.name}} campaign.subscription_topic_ids
{{campaign.subscription_topic_ids}} campaign.type
This returns the type of trigger for a campaign: behavioral (legacy segment-triggered), seg_attr (attribute or segment-triggered), transactional (event-triggered), form, date, object, or relationship.
For messages sent through our Transactional API, this returns transactional_message.
It also returns triggered_broadcast for an API-triggered broadcast or newsletter accordingly."
{{campaign.type}} content
{{content}} delivery_id
unsent. This is generated when the message is drafted or sent.{{delivery_id}} editor
bee (drag-and-drop email editor), html (code email editor), wysiwyg (rich text email editor), or rich (rich push editor). For Create or update person actions, in-app messages, Design Studio emails, SMS, and custom push, this value is blank.{{editor}} layout.id
{{layout.id}} layout.name
{{layout.name}} message.id
{{message.id}} of 200. Note that this identifies the action in your workflow, not the individual delivery instances. Every SMS delivery generated from the action would have a different {{delivery_id}}.For newsletters, the message.id is the value after templates in your URL. For example, the message.id here is 21 https://fly.customer.io/env/109950/composer/newsletters/1/templates/21.
{{message.id}} message.journey_id
journey.id value sent in our Reporting Webhooks.{{message.journey_id}} message.name
{{message.name}} message.preheader
{{message.preheader}} message.send_to_unsubs
{{message.send_to_unsubs}} message.subject
{{message.subject}} message.subscription_topic_ids
{{message.subscription_topic_ids}} message.type
email_action, delay_seconds_action, delay_time_window_action, split_randomized_action, webhook_action, twilio_action, slack_action, attribute_update_action, filter_match_delay_action, grace_period_action, push_action, conditional_wait_action, conditional_branch_action, multi_split_branch_action, random_cohort_branch_action, exit_action, static_seg_update_action, collection_query_action, create_event_action, multi_lang_branch_action, batch_update_action, in_app_action.{{message.type}} subscription_topic_name
lang='pt'. If the language doesn't match a translation in your subscription center, customers will see the default language.{% subscription_topic_name %}
{% subscription_topic_name lang='pt' %} Variable Tags
assign
{% assign var_name = 'value' %} {% assign favorite_food = 'apples' %} {{ favorite_food }} capture
{% capture about_me %}I am 28 and my favorite food is pasta.{% endcapture %} {{ about_me }} Iterative Tags
cycle
<ul>{% assign characters = "coyote,bugs,tweety" | split: "," %}
{% for character in characters %}
<li class="{% cycle 'odd', 'even' %}">{{ character }}</li>
{% endfor %}
</ul> <ul>
<li class='odd'>coyote</li>
<li class='even'>bugs</li>
<li class='odd'>tweety</li>
</ul> for loop
{% for item in array %}
{{ item }}
{% endfor %} {% comment %} You can output each item of the array {% endcomment %}
{% for member in members_of_band %}
{{member}}
{% endfor %}
{% comment %} If the items are objects, you can output properties from each object {% endcomment %}
{% for product in event.products %}
- {{ product.title }} x {{ product.price }}
{% endfor %} Conditional Tags
case
For example, you might use this to display different text depending on if a customer lives in a specific country.
{% case condition %}
{% when "value1" %}
text when condition is value1.
{% when "value2" or "value3" %}
text when condition is value2 or value3
{% else %}
text when condition does not match other conditions
{% endcase %} if
elsif to add multiple 'if' conditions and else for the block of code you want to execute if all conditions are false. Find more information about conditional liquid here.Hey
{% if customer.first_name %}
{{customer.first_name}}
{% else %}
there
{% endif %}
!
{% if customer.lastEventType == "sports" %}
You last attended a sports event, so we thought you might like to try out our leagues! Fill out our interest form below.
{% elsif customer.lastEventType == "theater" %}
You attended a theater event, so we thought you might like to try out our after show parties! Fill out our interest form below.
{% elsif customer.lastEventType %}
{% comment %} If the attribute exists and does not equal sports or theater, then this will render. {% endcomment %}
You last attended {{customer.lastEventType}}; we'd love to hear what other offerings you'd like from us in the form below.
{% else %}
{% comment %} If the attribute does not exist, this will render. {% endcomment %}
Let us know your interests in the form below so we can better serve you!
{% endif %} unless
{% unless product.name == "cool beans" %}
The beans are not cool.
{% endunless %} Logical Operators
and and or operators to combine logic statements to evaluate multiple conditions.and
{% if condition1 and condition2 %}
// do something if both condition1 and condition 2 are true
{% endif %} {% if customer.name == "bugs bunny" and event.episode_start == true %}
What's up doc?
{% else %}
That's all folks!
{% endif %} does not equal (!=)
!= to check that two values are not equal to each other.{% if customer.name != "daffy duck" %}
Duck season!
{% else %}
Wabbit season!
{%endif%} equals (==)
== to check if two values are equal to each other.{% if customer.name == "daffy duck" %}
Wabbit season!
{% else %}
Duck season!
{% endif %} greater than and greater than or equal to (>, >=)
> to match when one value is greater than another. Use >= to match when one value is greater than or equal to another.{% if val1 > val2 %}
{% comment %}do something if val1 is greater than val2{% endcomment %}
{% endif %} {% if customer.acct_age_years > 1 %}
Thanks for being with us these past years
{% else %}
Thanks for spending the last year with us!
{% endif %} less than and less than or equal to (<, <=)
< to match when one value is less than another. Use <= to match when one value is less than or equal to another.{% if val1 < val2 %}
{% comment %}do something if val1 is less than val2{% endcomment %}
{% endif %} {% if customer.purchases < 5 %}
Thanks for your support
{% else %}
Thanks for spending the last year with us!
{% endif %} or
{% if condition1 or condition2 %}
{% comment %}do something if either condition1 and condition 2 are true{% endcomment %}
{% endif %} {% if customer.name == "bugs bunny" or customer.group == "looney toons" %}
That's all folks!
{% else %}
See you later!
{% endif %} Timestamps and Dates
add_day
{{ <unix_timestamp> | add_day: <int_days> }} {{ 1477430251 | add_day: 7 }} add_month
{{ <unix_timestamp> | add_month: <int_months> }} {{ 1477430251 | add_month: 7 }} add_year
{{ <unix_timestamp> | add_year: <int_years> }} {{ 1477430251 | add_year: 4 }} countdown
The countdown timer cannot contain more than 60 frames. This limits the size of the animated GIF in your messages. So, if the resolution is set to seconds, the counter will stop after 60 seconds from when the person opens their message. The countdown image reloads when a person opens the message again, so the counter will always be relevant to the user's current time, but it cannot count indefinitely.
| Parameter | required | format | default | description |
| :--- | :--: | :--: | :--- | :--- |
| point | ✓ | integer | | The font size for the timer |
| time | ✓ | ISO 8601 timestamp | | The date and time you want to countdown to in the format YYYY-MM-DD hh:mm:ss (GMT). Remember to close the time in quotes, as the value includes a space. This field does not accept liquid variables. |
| fg | ✓ | hex color | | The foreground (font) hexidecimal color |
| bg | ✓ | hex color | | The background hexidecimal color |
| apng | | boolean | false | Determines whether to show your countdown as a gif (default) or animated PNG. Note that some browsers/email clients don't support apng images. |
| font | | string | inter, roboto | The font family for your timer |
| weight | | string | normal | The font weight, takes normal CSS font-weight values. |
| locale | | language code | en | The language you want to display: en (English), ru (Russian), jp (Japanese), zh (Chinese), pt (Portugese), es (Spanish), and fr (French) |
| looping | | boolean | false | Determines whether the countdown timer should restart after it finishes |
| resolution | | one of S, M, H, D | S | Determines how often the timer counts down—by the second, minute, hour, or day. |
| frames | | integer | 1 | Number of seconds you want to show, based on the resolution, where seconds: 60, minutes: 2, hours: 1, days: 1 |
{% countdown point:64 font:roboto weight:light fg:000000 bg:f2f6f9 time:"2022-07-04 12:00:00 (GMT)" locale:en looping:true resolution:S frames:2 %}
date
{{ 1483272000 | date: '%H:%M, %a, %b %d, %Y' }} 12:00, Sun, Jan 01, 2017 event_timestamp
now tag! This throws an error if the event has not been sent recently (within the last ~30 days).{{event_timestamp}} now
date.To modify date or time with add or subtract filters you must convert now into a unix timestamp first using date: '%s'. If you use our built in add_day, add_month, or add_year filters, you must convert the timestamp to an integer first. You can do this by using the plus filter to add 0 as shown in the second example below.
{{ 'now' | date: '%I:%M %p %B %d, %Y' }}
{{ 'now' | date: '%s' | plus: 0 | add_day: 1 | date: '%I:%M %p %B %d, %Y'}} 08:28 AM May 11, 2021
08:28 AM May 12, 2021 subtract_day
{{ <unix_timestamp> | subtract_day: <int_days> }} {{ 1477430251 | subtract_day: 7 }} subtract_month
{{ <unix_timestamp> | subtract_month: <int_months> }} {{ 1477430251 | subtract_month: 2 }} subtract_year
{{ <unix_timestamp> | subtract_year: <int_years> }} {{ 1477430251 | subtract_year: 4 }} timezone
now instead of a timestamp. You can convert to any time zone using numerical format, as an offset from UTC (e.g. -5 for EST). Otherwise, unix timestamps default to UTC. You can also specify the region using a string, like America/Los_Angeles. Check out our blog for more, common examples for formatting timestamps.{{ 1483272000 | timezone: '-8' | date: '%H:%M, %a, %b %d, %Y' }}
{{ 1483272000 | timezone: 'America/Los_Angeles' | date: '%H:%M, %a, %b %d, %Y' }}
{{ 1483272000 | timezone: 'America/Los_Angeles' | date: '%a., %-m/%d at %I:%M %P %Z' }} 04:00, Sun, Jan 01, 2017
04:00, Sun, Jan 01, 2017
Sun., 1/01 at 4:00 am PST Array Filters
for loop or grab items at a particular index of the array, to display information for your audience.compact
nil (empty) values from an array.{{ "mick, keith, nil, Charlie" | compact }} mick, keith, Charlie concat
concat does not remove duplicate entries unless you also use the uniq filter.{% assign stones = "mick, keith, ronnie, charlie" | split: ", " %}
{% assign beatles = "john, paul, george, ringo" | split: ", " %}
{% assign rolling_beatles = stones | concat: beatles %}
{{ rolling_beatles | join: ", " }} mick, keith, ronnie, charlie, john, paul, george, ringo first
acme.characters = ["Wile E Coyote", "Road Runner"]
{{ acme.characters | first }} Wile E Coyote join
acme.characters = ["Wile E Coyote", "Road Runner"]
{{ acme.characters | join: ', ' }} Wile E Coyote, Road Runner last
acme.characters = ["Wile E Coyote", "Road Runner"]
{{ acme.characters | last }} Road Runner limit
{% assign beatles = "john, paul, george, ringo" | split: ", " %}
{{ beatles | limit: 2 | join: ", " }} john, paul map
Array of objects: [{"name":"coyote"},{"name":"bugs"},{"name":"tweety"}]"
{% assign names = customer.characters | map: 'name' %} coyote, bugs, tweety remove
{% assign pl = customer.products | remove: customer.products[0] %}
- {{ customer.products.size }}
- {{ pl.size }} - 2
- 1 size
{{ "That's all, folks!" | size }}
{{ customer.latest_purchase | size }}
{{ objects.online_classes | size }}
{{ objects.online_classes.size }} 18 // The number of characters
4 // If `latest_purchase` is an array, this returns the number of items in the array. Otherwise, it returns a count of characters.
2 // The number of objects (onlines classes) that a person is related to.
2 // Using the size filter with dot notation sort
{% assign beatles = "paul, john, ringo, george" | split: ", " %}
{{ beatles | sort | join: ", " }} george, john, paul, ringo sort_natural
{{ "mick, keith, Charlie, Ronnie" | sort_natural }} Charlie, keith, mick, Ronnie sum
sum filter concatenates values in an array, including numbers; every value is treated as a string. You can specify an object property to sum, as shown in the third example below.The sum filter doesn't add number values together. But if you upgrade to our latest liquid, it will!
{% assign nums = '1,2,3' | split: ',' %}
{{ nums | sum }}
{% assign letters = 'a,b,c' | split: ',' %}
{{ letters | sum }}
{{ cart.products | sum: 'total_number' }} {% comment %} where `total_number` includes milk,cheese,eggs {% endcomment %}
{{ purchase.products | sum }} {% comment %} where `products` includes true,false {% endcomment %} 123
abc
milkcheeseeggs
truefalse {% comment %} would also concatenate numbers alongside booleans {% endcomment %} uniq
{% assign my_array = '"lions", "tigers", "bears", "bears", "lions"' %}
{{ my_array | uniq | join: ", " }} lions, tigers, bears where
All Players:
{% for player in customer.players %}
- {{ player.last_name }}
{% endfor %}
Baseball Players:
{% assign baseball_players = customer.players | where: "sport", "baseball" %}
{% for player in baseball_players %}
- {{ player.last_name }}
{% endfor %}
----------------------------
All products:
{% for product in customer.products %}
- {{ product.title }}
{% endfor %}
{% assign available_products = customer.products | where: "available" %}
Available products:
{% for product in available_products %}
- {{ product.title }}
{% endfor %} where_not
where_not, you provide two items separated by a comma: the property you want to match on and the value you want to match.All players:
{% for player in customer.players %}
- {{ player.last_name }}
{% endfor %}
Not baseball players:
{% assign not_baseball_players = customer.players | where_not: "sport", "baseball" %}
{% for player in not_baseball_players %}
- {{ player.last_name }}
{% endfor %} All players:
- Posey
- Maradona
- Montana
- Gretzky
- Jordan
Not baseball players:
- Maradona
- Montana
- Gretzky
- Jordan Number and Currency Filters
Some tags, like the currency and format_number, take an optional localization parameter, formatting the output for a specific locale. These tags use the format {{ 10 | currency: "en-us" }}, which would output $10.00.
A list of locales
af, ar, az, be, bg, bn, bs, ca, cs, cy, da, de-AT, de-CH, de-DE, de, dz, el-CY,
el, en-AU, en-CA, en-CY, en-GB, en-IE, en-IN, en-NZ, en-TT, en-US, en-ZA, en, eo,
es-419, es-AR, es-CL, es-CO, es-CR, es-EC, es-ES, es-MX, es-NI, es-PA, es-PE, es-US,
es-VE, es, et, eu, fa, fi, fr-CA, fr-CH, fr-FR, fr, gl, he, hi-IN, hi, hr, hu, id,
is, it-CH, it, ja, ka, km, kn, ko, lb, lo, lt, lv, mk, ml, mn, mr-IN, ms, na, nb,
ne, ng, nl, nn, oc, or, pa, pl, pt-BR, pt, rm, ro, ru, sc, sd, sk, sl, sn, sq, sr,
st, sw, ta, te, th, tl, tn, tr, tt, ug, ur, uz, vi, wo, za, zh-CN, zh-HK, zh-TW,
zh-YUE, ao, cd, ci, cm, eg, gh, ke, ls, ly, ma, mu, mw, mz, sz, tz, zm
currency
{{ 10 | currency }}
{{ 123456.78 | currency: "fr" }} $10.00
123 456,78€ format_number
NOTE: This replaces the former number_with_delimeter filter.
{{ 10000 | format_number }}
{{ 123456.78 | format_number: "fr" }} 10,000
123 456,78 round
{{ 4.32 | round }}
{{ 4.32 | round: 1 }} 4
4.3 rounded_currency
{{ 3.1415 | rounded_currency }} $3 Math Filters
divided_by
{{ 10 | divided_by: 2.5 }}
{{ 10 | divided_by: 4 }}
{{ 10 | divided_by: 4.0 }} 4.0
2
2.5 times
{{ 5 | times: 2 }}
{{ 10 | times: 2.5 }} 10
25.0 String Filters
append
{{ "What's all the hubbub, " | append: "bub?" }} What's all the hubbub, bub? base64_decode
{{ "Zm9vLmJhcg==" | base64_decode }} foo.bar base64_url_safe_decode
{{ "Zm9vLmJhcg" | base64_url_safe_decode }} foo base64_url_safe_encode
- and _ in place of + and /.{{ "foo" | base64_url_safe_encode }} Zm9vLmJhcg capitalize
{{ "hello world" | capitalize }} Hello world contains
{% if product.description contains 'lorem ipsum' %}
You might also be interested in Fillerama or Office Ipsum.
{% endif %} downcase
{{ 'STRING' | downcase }} {{ "ACME" | downcase }} acme escape
{{ "win+help@customer.io" | escape }} win%2Bhelp%40customer.io escape_once
{{ "1 < 2 & 3" | escape_once }} 1 < 2 & 3 hex_base64
hmac_sha256 filter.{{ "Customer.io" | hmac_sha256: "some_key" | hex_base64 }} bd23cyOCFrzicxM7w/ahKoJPQd0YTQlFLwXHZZ2ufVc= hmac_sha1
{{ "Customer.io" | hmac_sha1: "some_key" }} 2bdf556c9a75766f258d1e2824f6d0e31d1beedc hmac_sha256
{{ "Customer.io" | hmac_sha256: "some_key" }} 6dddb773238216bce273133bc3f6a12a824f41dd184d09452f05c7659dae7d57 htmlencode
lstrip
text{{ " Customer.io " | lstrip }}text textCustomer.io text md5
{{ "Customer.io" | md5 }} d52b6a207bf5255c05b1d0056230617e newline_to_br
<br />
Customer.io<br />
liquid<br /> pluralize
{{ int-val | pluralize: 'singular', 'plural'}} {{ event.item_count | pluralize: 'item', 'items' }} 3 items prepend
{{ "Sufferin' succotash!" | prepend: "Sylvester: " }} Sylvester: Sufferin' succotash! remove_first
{{ "folks that's all, folks!" | remove_first: "folks" }} that's all folks! remove_last
{{ "foobarbar" | remove_last: "bar" }} foobar remove
{{ "And that's all, folks!" | remove: ", folks" }} And that's all! replace
{{ "String you want to replace values in" | replace: "find-str", "replace-str" }} {{ "Coyotes never catch roadrunners!" | replace: "never", "always" }} Coyotes always catch roadrunners! replace_first
{{ "String you want to replace values in" | replace_first: "find-str", "replace-str" }} {{ "roller rocket roller skates" | replace_first: "roller", "awesome" }} awesome rocket roller skates replace_last
{{ "foobarbar" | replace_last: "bar", "foo" }} foobarfoo rstrip
text{{ " Customer.io " | rstrip }}text text Customer.iotext sha1
{{ "Customer.io" | sha1 }} c197ff0ae0a41983362f35ca972c544061c54d4c sha256
hmac_sha256.{{ "Customer.io" | sha256 }} 6dddb773238216bce273133bc3f6a12a824f41dd184d09452f05c7659dae7d57 slice
If the first argument is a negative number, the index is begins from the end of the string.
{{ "string" | slice: <req, index of char>, <optional, length of result> }} {{ "Customer.io" | slice: 3 }}
{{ "Customer.io" | slice: 3, 3 }}
{{ "Customer.io" | slice: '-4', 3 }} t
tom
r.i split
{% assign rolling_stones = "Mick, Keith, Ronnie, Charlie" | split: ", " %}
{% for member in rolling_stones %}
{{ member }}
{% endfor %} strip
text{{ " Customer.io " | strip }}text Customer.io strip_html
{{ "Eh, what's <i>up</i>, <b>Doc</b>?" | strip_html }} Eh, what's up, Doc? strip_newlines
{{ product.description | strip_newlines }} titlecase
{{ 'string' | titlecase }} {{ "rocket roller skates" | titlecase }} Rocket Roller Skates truncate
{{ "I knew I shoulda taken that left turn at Albuquerque." | truncate: 20 }} I knew I shoulda ... truncatewords
{{ "I knew I shoulda taken that left turn at Albuquerque." | truncatewords: 8 }} I knew I shoulda taken that left turn... upcase
{{ 'string' | upcase }} {{ 'acme' | upcase }} ACME url_decode
url_encode.{{ "%27Customer.io+is+great%27" | url_decode }} Customer.io is great url_encode
{{ "cool.person@example.com" | url_encode }} cool.person%40example.com Miscellaneous
comment
{% comment %} Don't display me! {% endcomment %} raw
{% raw %}
{{This}} is displayed exactly as typed.
{% endraw %} to_json
{{ customer | to_json }} sends all your customer data into a JSON variable.{{ customer | to_json }}