Skip to main content
Expressions in [[ ... ]], data-condition, data-ef-text, and similar attributes can call built-in functions. You can also register custom functions with registerTemplateFunction(name, fn) or registerTemplateFunctions({ name: fn, ... }).

Price display: when to use formatPrice vs as-is

Most checkout and cart values are already formatted (e.g. "$29.00"). Use them directly in [[ ... ]]. Use formatPrice() only when you need to display a raw number (e.g. *_raw keys or a computed number).
These are pre-formatted. Use [[ variable ]] only.
VariableExample
Checkout totalscheckout.product_price, checkout.retail_price, checkout.bump_total, checkout.subtotal_before_discount, checkout.discount_total, checkout.subtotal_after_discount, checkout.subtotal (alias), checkout.shipping, checkout.tax, checkout.total
Cart itemitem.price, item.total, item.retail_price, item.discount_total
Bump / linebump.price, line.price
In template: [[ checkout.total ]], [[ item.price ]], [[ bump.price ]]
Do not pass an already-formatted string into formatPrice (e.g. formatPrice(checkout.total, ...) or formatPrice(item.price, ...)). That can produce wrong or duplicated currency symbols.

formatPrice(value, currency?, locale?) / money / formatCurrency

Formats a numeric value as currency.
ParameterDescription
valueNumber (or parseable to number)
currencyOptional. Code (e.g. USD) or symbol. If omitted, uses checkout.currency or scope.currency or USD.
localeOptional. For Intl.NumberFormat.

Cart helpers

FunctionReturnsExample
lineTotal(item, quantityKey?, priceKey?)quantity × price for one item (default keys: quantity, price)[[ formatPrice(lineTotal(item), currency) ]] when item.total is not in scope
cartCount(items) / cart_count(items)Sum of item quantities[[ cartCount(cartItems) ]]
cartSubtotal(items, quantityKey?, priceKey?) / cart_subtotal(...)Numeric sum of line totals[[ formatPrice(cartSubtotal(cartItems), checkout.currency) ]]

String helpers

All coerce to string; null/undefined become empty string.
FunctionDescriptionExample result
upper / uppercaseUppercase”ALPHA”
lower / lowercaseLowercase”alpha”
capitalizeFirst character uppercase”Alpha”
titleCase / titleTitle case”Product Alpha”
camelCase / camelcamelCase”someLabel”
snakeCase / snakesnake_case”some_label”
kebabCase / kebabkebab-case”some-label”

Custom functions

Register from application or plugin code:
import { registerTemplateFunction, registerTemplateFunctions } from './utils/templateProcessor.js';

registerTemplateFunction('myFormat', (value) => {
  return value != null ? String(value).toUpperCase() : '';
});

registerTemplateFunctions({
  double: (n) => Number(n) * 2,
  greet: (name) => `Hello, ${name || 'Guest'}!`
});
Then in templates: [[ myFormat(item.name) ]], [[ double(item.quantity) ]], [[ greet(checkout.customer.first_name) ]].

Summary

  • Price display: Use the table above: pre-formatted keys as-is; formatPrice only for raw values or computed numbers.
  • Cart: cartCount, cartSubtotal, lineTotal; combine with formatPrice when you need a formatted string from a number.
  • Strings: upper, lower, capitalize, titleCase, camelCase, snakeCase, kebabCase (and aliases).
  • Custom: registerTemplateFunction / registerTemplateFunctions.
Next: Cart and Checkout.