# Helpers for receipt templates Use these helpers to build receipt templates. Receipt templates support both built-in `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. ```handlebars {{#each items}} {{@index}}: {{this.name}} - {{this.price}} {{/each}} ``` Special variables inside `#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 item - `this`: references the current item - `../`: access parent context #### #if Conditionally render content when an expression evaluates to true. ```handlebars {{#if customer.name}} Welcome, {{customer.name}}! {{else}} Welcome, Guest! {{/if}} ``` #### #unless Inverse of `#if`. Renders content when an expression evaluates to false. ```handlebars {{#unless paid}} Payment Required {{/unless}} ``` #### #with Create a new context scope to shorten property paths. ```handlebars {{#with customer}} {{name}} - {{email}} {{/with}} ``` ### Currency formatting #### formatCurrency Format monetary values using `Dinero.js` with the configured currency settings. All currency values are handled using Dinero.js for precise calculations. ```handlebars {{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): use `numeric` to output only the amount without a currency symbol. ### Item grouping #### groupByFacet Group line items by a facet and calculate totals per group. ```handlebars {{#groupByFacet line_items 'facetName'}} {{groupKey}} ({{totalQuantity}} items) subtotal: {{formatCurrency subtotal}} {{/groupByFacet}} ``` Block context properties: - `groupKey`: facet value for the group - `totalQuantity`: total number of items in the group - `subtotal`: `Dinero.js` object for the group total - `items`: 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. ```handlebars {{logo key1 key2}} ``` Parameters for this helper include the following: - `key1`: first key segment used to locate the logo - `key2`: second key segment used to locate the logo #### barcode Generate commands to print a Code 128 barcode including Human Readable Interpretation (HRI). ```handlebars {{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. ```handlebars {{truncate description 20}} ``` Parameters for this helper include the following: - `str`: string to truncate - `len`: maximum length before truncation ### Custom conditional helpers You can nest custom conditional helpers for compound conditions. #### if\_gt (greater than) Render content if the `value` is greater than the `threshold`. ```handlebars {{#if_gt value threshold}} Content shown if value > threshold {{/if_gt}} ``` #### if\_gte (greater than or equal to) Render content if `value` is greater than or equal to the `threshold`. ```handlebars {{#if_gte value threshold}} Content shown if value >= threshold {{/if_gte}} ``` #### if\_lt (less than) Render content if `value` is less than the `threshold`. ```handlebars {{#if_lt value threshold}} Content shown if value < threshold {{/if_lt}} ``` #### if\_lte (less than or equal to) Render content if the `value` is less than or equal to the `threshold`. ```handlebars {{#if_lte value threshold}} Content shown if value <= threshold {{/if_lte}} ``` #### if\_eq (equal) Render content if `value` strictly equals `threshold`. ```handlebars {{#if_eq value threshold}} Content shown if value === threshold {{/if_eq}} ``` #### if\_ne (not equal) Render content if `value` does not strictly equal `threshold`. ```handlebars {{#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. ```handlebars {{! 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. | ## Related pages - [Area overview page with navigation](/instore.md) - [Previous page: Refund receipt template](/instore/implement-instore/receipts/refund-receipt.md) - [Search documentation and API specs](/search.md)