Functions Available in Templates
The functions a theme can call, grouped by what they are for, with the ones that matter most called out.
Around forty five functions are available in any theme template. These are the ones you will actually use.
Money and Formatting
| Function | Does |
|---|---|
money(amount) |
Formats in the shop's currency |
price(product) |
What this shopper pays, including group pricing |
currency_format(amount) |
Lower level formatting |
local_date(date, format) |
Formats for the shopper's locale |
local_number(n) |
Number formatting |
number_format(n, decimals) |
Explicit formatting |
round(n, precision) |
Rounding |
Use money(), never your own formatting
It handles the shop's currency, the symbol, which side it goes on, and the shopper's market. A hardcoded dollar sign is the single most common fault in a submitted theme, and it is invisible to the developer because it only shows up for the merchant's overseas customers.
The same applies to price(). Printing product.price directly ignores group pricing, so a wholesale customer sees the retail price on your listing and the trade price at checkout, and writes to the merchant about it.
Catalogue
| Function | Does |
|---|---|
featured_products(ids, limit, source) |
A row of products. source is featured, new or bestselling |
active_categories() |
Categories for navigation |
group_price(product) |
The price for this shopper's group |
is_wholesale_customer() |
Whether this shopper is trade |
customer_in_group(group) |
Membership test |
Content
| Function | Does |
|---|---|
navigation_menu(location) |
A menu the merchant built |
recent_blog_posts(limit) |
Posts from the built-in blog |
reading_time(html) |
Minutes to read an article, at 200 words a minute. Null when empty |
external_blog_posts(limit) |
Posts from a blog hosted elsewhere |
upcoming_events(limit) |
Events |
render_form(slug) |
A form the merchant built |
external_links(html) |
Makes links in merchant-written content open safely |
Run merchant-written HTML through external_links() rather than printing it raw. It is what stops a pasted link opening in the same window and losing the shopper.
Sections
Everything a section partial needs. Use these rather than writing the same logic per section: a tint chosen on one section has to come out the same colour as a tint chosen on another, or a page looks accidental and the merchant cannot say why.
| Function | Does |
|---|---|
section_style(settings, spacing, background) |
The whole style attribute for a section: padding above and below, and the background. The last two arguments are the defaults to use when the merchant has chosen nothing |
section_box(settings) |
Where a section that is not full width sits across the page, from its box_align. Empty for centered |
section_background(settings) |
Just the background, where a partial needs it apart from the padding |
section_partial(type) |
The partial a section type draws from, read from the manifest. Use it to render a section nested inside another |
gift_card_options() |
What the gift card form needs, and whether the shop sells them at all |
content_places_form(html) |
Whether merchant-written content already places a form with a token, so a template does not draw a second one below it |
{% set s = section.settings|default({}) %}
<section style="{{ section_style(s) }}">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8" style="{{ section_box(s) }}">
...
</div>
</section>
Filters
| Filter | Does |
|---|---|
rich_content |
Merchant-written HTML, with editor images resolved and {form, slug} tokens expanded. Use it for anything a merchant typed |
shop_date, shop_time, shop_datetime |
Formatted in the shop's own date and time settings, not the server's |
Shop and Settings
| Function | Does |
|---|---|
store_name() |
The shop's name |
theme_config(key) |
A theme setting |
theme_has(path) |
Whether this theme ships a file, so an optional template can fall back |
tenant_setting(key, default) |
A shop setting |
language_config() |
Active languages |
markets() |
Configured markets |
countries() |
Country list for forms |
weight_unit(), dimension_unit() |
The shop's units |
Customer
auth_check(), auth_guest(), auth_user(), auth_guard().
Use auth_check() to vary what is shown, never to hide something that should be protected. Anything that must not be seen is kept off the page by the shop, not by a template condition.
Assets and Plumbing
| Function | Does |
|---|---|
cdn_asset(path) |
An asset through the CDN |
storage_url(path) |
An uploaded file |
csrf_field() |
The token for a form |
app_scripts() |
Scripts registered by installed apps |
translate(key) |
A translated string |
Call app_scripts() in your layout
Apps a merchant installs register scripts here. A theme that never calls it silently breaks every app they bought, and the merchant will report it as the app being broken rather than the theme.
Plugin Hooks
plugin_hook(name), plugin_render(name), plugin_has(name).
Call plugin_hook() at the obvious extension points: above and below the product description, in the basket, at the top and bottom of the checkout, in the footer. Each one is somewhere an installed app can appear.
A theme with no hooks is a theme that quietly breaks the things a merchant adds to their shop.
Checkout and Payments
payment_gateway_components(), payment_gateway_component(gateway), express_checkout_data(), pay_later_data().
Do not rebuild the checkout casually
These render the live payment forms for whichever gateways the merchant has enabled. If you customise the checkout, test every gateway, including the wallet buttons, which only appear on devices that support them. A checkout that works with one processor and silently breaks another is worse than one you left alone.
Requests and Translation
request(), request_get(key), input_get(key), old(key), config(key), csrf_field(), translate(key).
Wrap every piece of text a shopper reads in translate(), even in a theme that ships in one language. Retrofitting it later means touching every template.
