Filters modify variables before output. Theme Raed includes Twig’s built-in filters plus Salla-specific filters.
Salla filters
money
Formats a number as currency with the store’s currency symbol.
{{ product.price|money }}
{# Output: "100.00 SAR" or "١٠٠ ر.س" #}
{{ cart.total|money }}
{{ item.sale_price|money }}
Numeric value to format as currency
The output format depends on:
- Store currency (
currency.symbol)
- Language direction (RTL/LTR)
- Number format settings (
store.settings.arabic_numbers_enabled)
cdn
Generates a CDN URL for assets with optional dimensions.
{{ 'images/logo.png'|cdn }}
{# Output: CDN URL for the image #}
{{ store.logo|cdn }}
{{ product.image.url|cdn }}
asset
Generates a URL for theme assets (JS, CSS, images).
<script src="{{ 'app.js' | asset }}"></script>
<script src="{{ 'product.js' | asset }}"></script>
<script defer src="{{ 'checkout.js' | asset }}"></script>
json_encode
Encodes a value as JSON for use in JavaScript or HTML attributes.
<salla-count-down
pre-order='{{ product.preorder|json_encode }}'
boxed
labeled>
</salla-count-down>
<salla-cart-item-offers
offers="{{ item.detailed_offers|json_encode }}">
</salla-cart-item-offers>
trans
Translates a key to the current language.
{{ trans('pages.cart.empty_cart') }}
{{ trans('common.elements.back_home') }}
{{ trans('pages.products.read_more') }}
Translation keys are defined in the theme’s language files. Merchants can customize translations via the Salla dashboard.
pluralize
Returns the singular or plural form based on a count.
{{ pluralize('pages.products.sold_times', product.sold_quantity)|raw }}
{# Output: "1 time" or "5 times" depending on quantity #}
String filters
raw
Outputs HTML without escaping. Use for trusted HTML content.
{{ product.description|raw }}
{{ store.description|raw }}
{{ product_desc|raw }}
Only use raw for content you trust. Never use it with user input to prevent XSS attacks.
replace
Replaces text within a string.
{% set product_desc = product.description|replace({" ":"\n"}) %}
{{ product.name|replace({'&': 'and'}) }}
Object with search/replace pairs
upper
Converts string to uppercase.
{{ product.name|upper }}
{# "PRODUCT NAME" #}
lower
Converts string to lowercase.
{{ product.name|lower }}
{# "product name" #}
title
Converts string to title case.
{{ product.name|title }}
{# "Product Name" #}
capitalize
Capitalizes the first character.
{{ status|capitalize }}
{# "Active" #}
trim
Removes whitespace from both ends.
length
Returns the length of a string or array.
{% if product.name|length > 50 %}
{{ product.name|slice(0, 50) ~ '...' }}
{% else %}
{{ product.name }}
{% endif %}
Array filters
slice
Extracts a portion of an array.
{% for product in section.products|slice(0, 4) %}
<!-- First 4 products -->
{% endfor %}
{% for product in section.products|slice(0, main_product ? 4 : 8) %}
<!-- Dynamic slice -->
{% endfor %}
Number of items to extract
first
Returns the first element.
{% if loop.first %}
<img loading="eager" src="{{ product.images|first }}">
{% endif %}
last
Returns the last element.
{{ product.images|last }}
join
Joins array elements with a separator.
channels="{{ product.notify_availability.channels|join(',') }}"
{# Output: "sms,email" #}
{{ tags|join(', ') }}
{# Output: "tag1, tag2, tag3" #}
String to insert between elements
sort
Sorts an array.
{% for tag in product.tags|sort %}
{{ tag.name }}
{% endfor %}
reverse
Reverses an array.
{% for item in cart.items|reverse %}
<!-- Items in reverse order -->
{% endfor %}
Number filters
round
Rounds a number.
{{ product.price|round }}
{# 99.5 → 100 #}
{{ product.price|round(2) }}
{# 99.567 → 99.57 #}
Formats a number with thousands separator.
{{ product.sold_quantity|number_format }}
{# 1000 → "1,000" #}
abs
Returns absolute value.
Date filters
date
Formats a date.
{{ product.created_at|date('Y-m-d') }}
{# 2024-01-15 #}
{{ product.created_at|date('F j, Y') }}
{# January 15, 2024 #}
{{ product.discount_ends|date('M d, Y H:i') }}
{# Jan 15, 2024 14:30 #}
Conditional filters
default
Provides a default value if variable is undefined or empty.
{{ product.subtitle|default('No subtitle available') }}
{{ image.alt|default(product.name) }}
{{ theme.settings.get('imageZoom')|default('enabled') }}
Type checking
iterable
Checks if a value is iterable (array or object).
{% if image.video_url is iterable %}
{{ image.video_url|first }}
{% else %}
{{ image.video_url }}
{% endif %}
Escaping filters
escape (e)
Escapes HTML characters (applied by default).
{{ product.name|escape }}
{{ product.name|e }}
{# Same as {{ product.name }} #}
url_encode
Encodes a string for use in URLs.
<a href="/search?q={{ query|url_encode }}">
Search results
</a>
Chaining filters
Filters can be chained together:
{{ product.name|upper|trim }}
{{ product.description|replace({" ":"\n"})|raw }}
{{ product.price|round(2)|number_format }}
{{ store.description|trim|raw }}
Common patterns
Price display
{% if product.is_on_sale %}
<span class="text-red-800">{{ product.sale_price|money }}</span>
<span class="line-through">{{ product.regular_price|money }}</span>
{% else %}
<span>{{ product.price|money }}</span>
{% endif %}
Image optimization
<img
src="{{ product.image.url|cdn }}"
alt="{{ product.image.alt|default(product.name) }}"
{% if loop.first %}
loading="eager"
fetchpriority="high"
{% else %}
loading="lazy"
{% endif %}
>
Truncate text
{% if product.name|length > 50 %}
{{ product.name|slice(0, 50)|trim ~ '...' }}
{% else %}
{{ product.name }}
{% endif %}
Safe HTML output
<div class="product-description">
{{ product.description|raw }}
</div>
Conditional assets
{% if product.has_3d_image %}
<script type="module" defer src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>
{% endif %}
{% if theme.settings.get('enable_add_product_toast', true) %}
<script defer src="{{ 'add-product-toast.js'|asset }}"></script>
{% endif %}