Use these helpers to build receipt templates.
Handlebars
helpers and custom helpers specific to receipts. This page lists the helpers, their purpose, and examples.Overview
- Use built-in helpers for generic control flow.
- Use custom helpers for receipt and device-specific tasks (for example, grouping line items or sending printer commands to registered peripherals).
- Pass only the required data to keep templates readable and maintainable.
Handlebars helpers
Basic block helpers
#each
Iterate over array items or object properties.
{{#each items}}
{{@index}}:
{{this.name}}
-
{{this.price}}
{{/each}}
#each
:@index
: zero-based index of the current item in the array@key
: current property name when iterating over object properties@first
: true if this is the first item@last
: true if this is the last itemthis
: references the current item../
: access parent context
#if
Conditionally render content when an expression evaluates to true.
{{#if customer.name}}
Welcome,
{{customer.name}}!
{{else}}
Welcome, Guest!
{{/if}}
#unless
#if
. Renders content when an expression evaluates to false.{{#unless paid}}
Payment Required
{{/unless}}
#with
Create a new context scope to shorten property paths.
{{#with customer}}
{{name}}
-
{{email}}
{{/with}}
Currency formatting
formatCurrency
Dinero.js
with the configured currency settings. All currency values are handled using Dinero.js for precise calculations.{{formatCurrency amount 'numeric'}}
{{! Formats without currency symbol }}
{{formatCurrency amount}}
{{! Formats with currency symbol }}
Parameters for this helper include the following:
amount
:Dinero.js
object representing the monetary value.format
(optional): usenumeric
to output only the amount without a currency symbol.
Item grouping
groupByFacet
Group line items by a facet and calculate totals per group.
{{#groupByFacet line_items 'facetName'}}
{{groupKey}}
({{totalQuantity}}
items) subtotal:
{{formatCurrency subtotal}}
{{/groupByFacet}}
Block context properties:
groupKey
: facet value for the grouptotalQuantity
: total number of items in the groupsubtotal
:Dinero.js
object for the group totalitems
: array of grouped items
Printer commands
logo
Generate printer commands to output a stored logo. Supports Epson and Star command sets selected via device configuration.
{{logo key1 key2}}
Parameters for this helper include the following:
key1
: first key segment used to locate the logokey2
: second key segment used to locate the logo
barcode
Generate commands to print a Code 128 barcode including Human Readable Interpretation (HRI).
{{barcode value}}
Parameters for this helper include the following:
value
: data to encode
Text formatting
truncate
Truncate text to a maximum length at a word boundary and append an ellipsis. Helps content fit within the printer width.
{{truncate description 20}}
Parameters for this helper include the following:
str
: string to truncatelen
: maximum length before truncation
Custom conditional helpers
You can nest custom conditional helpers for compound conditions.
if_gt (greater than)
value
is greater than the threshold
.{{#if_gt value threshold}}
Content shown if value > threshold
{{/if_gt}}
if_gte (greater than or equal to)
value
is greater than or equal to the threshold
.{{#if_gte value threshold}}
Content shown if value >= threshold
{{/if_gte}}
if_lt (less than)
value
is less than the threshold
.{{#if_lt value threshold}}
Content shown if value < threshold
{{/if_lt}}
if_lte (less than or equal to)
value
is less than or equal to the threshold
.{{#if_lte value threshold}}
Content shown if value <= threshold
{{/if_lte}}
if_eq (equal)
value
strictly equals threshold
.{{#if_eq value threshold}}
Content shown if value === threshold
{{/if_eq}}
if_ne (not equal)
value
does not strictly equal threshold
.{{#if_ne value threshold}}
Content shown if value !== threshold
{{/if_ne}}
Example combining built-in and custom helpers
The following example uses grouping, conditional helpers, truncation, currency formatting, and a barcode. It assumes device peripherals (for example a printer) are already registered.
{{! Logo at the top }}
{{logo 1 1}}
{{#if store.name}}
{{store.name}}
{{else}}
Default Store
{{/if}}
{{! Group items by product type }}
{{#groupByFacet line_items 'productType'}}
===
{{groupKey}}
===
{{#each items}}
{{! Show item number for non-first items }}
{{#unless @first}}
{{@index}}.
{{/unless}}
{{truncate description 20}}
{{! Format price based on amount }}
{{#if_gt price.amount 10000}}
**{{formatCurrency price}}**
{{else}}
{{formatCurrency price}}
{{/if_gt}}
{{/each}}
{{#if_gt totalQuantity 1}}
Group Total ({{totalQuantity}}
items):
{{formatCurrency subtotal}}
{{/if_gt}}
{{/groupByFacet}}
{{! Only show barcode if order number exists }}
{{#with order_number}}
{{barcode this}}
{{/with}}
Best practices
Follow these practices when building receipt templates:
- Truncate long text to avoid unintended wrapping.
- Use conditional helpers to cover pricing or quantity edge cases.
- Group related items with
groupByFacet
for readability. - Use built-in context variables (
@index
,@first
,@last
) for positional logic. - Use
../
to access a parent context inside nested blocks. - Combine built-in and custom helpers instead of adding complex logic to a single helper.
- Use the appropriate currency formatting based on display context.
Troubleshooting
If a receipt template does not render as expected, check the following:
Symptom | Resolution |
---|---|
Currency output looks wrong | Ensure each price is a Dinero.js object and not a raw number. |
Nested data not found | Confirm parent references use ../ at the correct depth. |
Grouping empty or incorrect | Verify the facet name string matches the data exactly. |