Skip to content

Liquid filters

A filter transforms the value on its left: {{ value | filter }}, or {{ value | filter: argument1, argument2 }}. Filters chain from left to right.

{{ listing.title | escape | truncate: 40 }}

Output is not escaped by default: {{ value }} prints the value as it is. Escape anything typed by a member (titles, descriptions, names, query parameters you rebuild) with escape, rich_html or safe_url, as described below.

{{ amount | money }} · {{ amount | money: currency }}

Formats a number as a price in the storefront’s language. Without an argument, the currency is the marketplace’s currency. Pass an ISO 4217 code to force another one, for example the currency an order was paid in.

{{ listing.price | money }}
{{ order.total | money: order.currency }}
Output on an English storefront in euros
€1,234.50
€89.00

On a French storefront the same values print 1 234,50 € and 89,00 €. A value that is not a number is converted to one first.

{{ number | number_format }} · {{ number | number_format: decimals }}

Groups thousands the way the storefront’s language does. Use it for any number shown to a visitor that is not a price: mileage, surface, capacity. decimals is the minimum number of decimals; up to three are kept when the number has them.

{{ 110000 | number_format }}
{{ 1234 | number_format: 2 }}
{{ 1234.5 | number_format }}
Output on an English storefront
110,000
1,234.00
1,234.5

A French storefront prints 110 000, 1 234,00 and 1 234,5.

An empty value returns nothing, so {% if %} guards keep working; a value that is not a number is returned untouched.

{{ image | img_url }} · {{ image | img_url: 'WIDTHxHEIGHT' }}

Returns the URL of an uploaded image (a listing picture, an avatar, a blog cover…). With a size, returns the URL of a copy resized to that size, which loads much faster than the original. SVG files are never resized.

<img src="{{ listing.cover | img_url: '600x400' }}" alt="{{ listing.title | escape }}">
<div style="background-image: url('{{ user.avatar | img_url: '400x400' }}')"></div>

The URL is made safe to print inside an attribute: a non-web scheme is dropped and the characters that could close the attribute are encoded.

{{ 'file.ext' | asset_url }}

Returns the URL of a file of your theme: one you created in the theme editor’s Assets, or one the theme ships. The URL carries a version stamp that changes when the file changes, so visitors get the new file as soon as you save it. See Assets.

{{ 'custom.css' | asset_url | stylesheet_tag }}
{{ 'custom.js' | asset_url | script_tag }}
<img src="{{ 'badge.png' | asset_url }}" alt="">

A file that exists nowhere returns the text Error: <file> not found, which you will see in the page source.

{{ url | stylesheet_tag }}

Wraps a URL in a stylesheet link.

{{ 'custom.css' | asset_url | stylesheet_tag }}
Output
<link rel="stylesheet" href="/assets/…/custom.css?v=1760385600"/>

{{ url | script_tag }}

Wraps a URL in a script tag. The tag is marked as necessary for the cookie consent apps, so a consent banner does not block it.

{{ 'custom.js' | asset_url | script_tag }}
Output
<script src="/assets/…/custom.js?v=1760385600" data-cookieconsent="necessary"></script>

{{ 'translation.key' | t }}

Returns the theme string stored under that key, in the storefront’s language. See Translations.

<h1>{{ "general.contact.title" | t }}</h1>

A key that exists in neither the storefront’s language nor English prints nothing, not the key.

{{ 'translation.key' | tn: count }}

Picks the plural form of a string. The filter appends a suffix to the key according to count and translates the result: .zero for 0, .one for 1, .two for 2, .other for anything else.

<strong>{{ vendor_sales_count }}</strong>
{{ 'account.dashboard.vendor_sales_count' | tn: vendor_sales_count }}

With vendor_sales_count equal to 3, this reads the key account.dashboard.vendor_sales_count.other.

{{ date | date: format }} · {{ date | date: format, timezone }}

Formats a date in the marketplace’s time zone. The format is required. It accepts two syntaxes:

  • PHP date characters, such as d/m/Y H:i or Y-m-d;
  • % directives: %Y year, %y two-digit year, %m month, %d day, %H hours, %M minutes, %S seconds, %B month name, %b short month name, %A day name, %a short day name. Text around them is kept.

'r' prints an RFC 2822 date. Pass a time zone identifier as a second argument to override the marketplace’s.

{{ article.created | date: 'd/m/Y' }}
{{ article.created | date: '%d %B %Y' }}
{{ article.created | date: 'H:i', 'America/New_York' }}
Output
13/10/2026
13 October 2026
09:30

A date given as text without a time zone is read as UTC. An empty value returns nothing.

{{ text | truncate: length }} · {{ text | truncate: length, ellipsis }}

Shortens a text and appends an ellipsis (... by default). Kreezalid’s version replaces the standard one: the length of the ellipsis is taken off length before the text is cut, so the visible result is shorter than length.

{{ 'Hello wonderful world' | truncate: 10 }}
{{ 'Hello wonderful world' | truncate: 12, '…' }}
{{ 'Short' | truncate: 10 }}
Output
Hell...
Hello wo…
Short

The ellipsis’s length is counted in bytes: … counts as three.

Without a numeric length, the text is returned untouched.

{{ text | escape }}

Encodes the HTML special characters, quotes included. Use it on every value typed by a member that you print as text or inside an attribute.

<img alt="{{ listing.title | escape }}" src="…">

{{ text | rich_html }}

Prints text written by a buyer or a vendor as HTML, safely. Plain text is escaped and its line breaks are kept; text that contains markup (opening hours with <br>, a video embed) keeps a safe subset of HTML and loses anything that could run a script. Use it for descriptions and long text attributes printed as content. Inside an attribute value, use escape instead.

<div class="listing-description">{{ listing.description | rich_html }}</div>

{{ url | safe_url }}

Keeps a URL only when it is http, https or relative, and returns an empty string otherwise. Use it before printing a link a member entered into href, then escape it: escape alone keeps the value inside the attribute but would still let a javascript: link run on click.

<a href="{{ vendor.company.website_url | safe_url | escape }}" rel="nofollow">Website</a>

{{ rating | stars }}

Draws a rating out of five as star icons: full stars, a half star for a decimal rating, then empty stars, wrapped in <span class="rate">.

{{ 4.5 | stars }}

An empty rating returns nothing.

{{ option_id | option }}

Returns the label of a choice of a listing or profile attribute (a select, a radio button, a checkbox list) from the choice’s id. An id that matches no choice is returned as it is. You rarely need it: listing.attributes and vendor.attributes already hold the labels. Use it when you only have a choice id, for example one you stored in a query parameter.

{{ request.query_params.color | option }}

{{ country_code | countryFullname }}

Returns a country’s name, in the storefront’s language, from its two-letter code (fr, FR). Mind the capital letter in the filter name.

{{ 'fr' | countryFullname }}
Output on an English storefront
France

An unknown code returns an error sentence, so test the value first.

{{ address | format_address }}

Prints an address as HTML lines joined by <br>: company, then name, street, street complement, postcode and city, state, country. Every part is escaped. It reads the keys company, gender, name, fname, lname, street, street_option, postcode, city, state and country, and skips the empty ones.

<address>{{ order.billing_address | format_address }}</address>

{{ file_url | clean_filename }}

Returns a readable file name from the URL of an uploaded file: the path is dropped, as well as the numeric prefix and the random suffix added on upload.

{{ 'https://cdn.example.com/files/1696_price-list_j4pm3_12345678.pdf' | clean_filename }}
Output
price-list.pdf

{{ array | shuffle }}

Returns the items of an array in a random order. Anything that is not an array is returned as it is.

{% assign picks = featured | shuffle %}
{% for listing in picks limit: 3 %}…{% endfor %}

Pages can be cached: do not rely on a new order at every page view.

{{ value | debug }}

Prints a value as indented JSON inside <pre>, to discover what a template receives. Remove it before you leave the editor: everything it prints is visible to every visitor.

{{ listing | debug }}

These standard filters work as in the Liquid reference, with the differences noted.

Filter Example Result
append {{ 'a' | append: 'b' }} ab
prepend {{ 'b' | prepend: 'a' }} ab
capitalize {{ 'hello world' | capitalize }} Hello World (every word)
downcase {{ 'Hello' | downcase }} hello
upcase {{ 'hello' | upcase }} HELLO
strip, lstrip, rstrip {{ ' x ' | strip }} x
strip_html {{ '<p>x</p>' | strip_html }} x
strip_newlines {{ text | strip_newlines }} text on one line
newline_to_br {{ text | newline_to_br }} line breaks as <br />
escape_once {{ '&lt;b&gt;' | escape_once }} does not encode twice
replace, replace_first {{ 'a-b-c' | replace: '-', ' ' }} a b c
remove, remove_first {{ 'a-b' | remove: '-' }} ab
split {% assign parts = 'a,b' | split: ',' %} an array
slice {{ 'abc' | slice: 1, 2 }} bc
truncatewords {{ 'one two three' | truncatewords: 2 }} one two...
url_encode, url_decode {{ 'a b' | url_encode }} a+b
size {{ listings | size }} number of items, or of characters
first, last {% assign cover = listing.medias | first %} first or last item
join {{ tags | join: ', ' }} items joined (space by default)
map {{ listings | map: 'title' | join: ', ' }} one field of each item
where {% assign external = menu.links | where: 'target', '_blank' %} items whose field equals the value; with one argument, items whose field is set and not false
sort {% assign sorted = listings | sort: 'price' %} sorted, by a field when given
sort_key {% assign sorted = hash | sort_key %} a hash sorted by key
uniq {{ list | uniq | join }} duplicates removed
reverse {% assign recent = listings | reverse %} arrays only (a string raises an error)
json {{ listing.attributes | json }} the value as JSON, to hand to a script
default {{ vendor.business_name | default: vendor.public_name }} the argument when the value is empty, false or null
raw {{ value | raw }} the value unchanged
string {{ 42 | string }} the value as text
plus, minus, times, divided_by, modulo {{ 10 | divided_by: 4 }} 2.5 (no integer division)
round {{ 3.14159 | round: 2 }} 3.14
ceil, floor {{ 4.1 | ceil }} 5

date and truncate are replaced by the Kreezalid versions described above.