How to use the tool and the Handlebars template language with custom helpers.
Paste a valid bearer token into the token field in the toolbar and click Set Token. The token is stored in your browser's session and used for all API calls (load, save, delete, preview).
| Pane | Purpose |
|---|---|
| Source Data (left) | Paste or drop a JSON file containing the specification data that will feed into the template. Click Format to pretty-print. |
| Template (center) | Write your Handlebars + HTML template. Supports syntax highlighting and autocomplete. |
| Preview (right) | Rendered HTML output. Click Run Preview to render the template against the source data via the backend. Toggle Raw HTML to see the generated markup. |
Click Partials in the toolbar to manage reusable template fragments. Create named partials and reference them in your template with {{> partial-name}}. Partials are saved per-template.
Drop a .json file onto the Source Data pane to load it instantly.
| Syntax | Description |
|---|---|
{{PropertyName}} | Output a value (HTML-escaped) |
{{{PropertyName}}} | Output raw HTML (unescaped) — use for trusted content like ingredient lists |
{{Object.Nested.Value}} | Dot-path access to nested properties |
{{#if DisplayOnPack}}
<p>{{Value}}</p>
{{/if}}
{{#if (equals Status "active")}}
<span>Active</span>
{{else}}
<span>Inactive</span>
{{/if}}
{{#each Nutrients}}
<tr>
<td>{{Nutrient.Name}}</td>
<td>{{RoundedValueString}} {{UnitOfMeasure.Abbreviation}}</td>
</tr>
{{/each}}
| Syntax | Meaning |
|---|---|
{{this}} | Current item in an {{#each}} loop |
{{@index}} | Zero-based index in loop |
{{@first}} / {{@last}} | Boolean — first or last iteration |
{{../PropertyName}} | Access parent context from inside a block |
{{#with Chapters.Labeling.ProductInformationSection}}
<h2>{{CommercialName.CommercialName}}</h2>
<p>{{LegalName.LegalName}}</p>
{{/with}}
equalsCompares two values for strict (case-sensitive) equality. Use inside {{#if}} blocks.
{{#if (equals Status "active")}}Active{{/if}}
{{#if}}.containsChecks whether a string contains a substring.
{{#if (contains IngredientList "milk")}}
<span class="allergen">Contains milk</span>
{{/if}}
replaceReplaces all occurrences of a substring.
{{replace ProductCode "-" ""}}
joinConcatenates a collection into a single string with a separator.
{{join AllergenNames ", "}}
nutriscore-imgRenders the full Nutri-Score SVG for a grade (A–E).
{{{nutriscore-img NutriscoreGrade}}}
{{{ }}} because this helper outputs raw HTML (an inline SVG).dms-imgRenders an inline <img> tag for a file stored in the Document Management System (DMS). The engine pre-fetches referenced files as base64 data URIs before template execution — no browser authentication is needed to display the images.
{{{dms-img Claim.Logo.FileId}}}
{{! With alt text }}
{{{dms-img Claim.Logo.FileId Claim.ClaimName}}}
{{{ }}} because this helper outputs raw HTML (an <img> tag).| # | Argument | Required | Description |
|---|---|---|---|
| 1 | File ID | Yes | A GUID referencing a DMS file |
| 2 | Alt text | No | Alternative text for the image. Defaults to empty string. |
<img src="data:image/png;base64,..." alt="Organic" />dms-img (performance optimisation).lowercaseConverts a string value to lowercase.
{{lowercase UnitOfMeasure.Name}}
uppercaseConverts a string value to uppercase.
{{uppercase Nutrient.Name}}
t (translate)Looks up a translation key from a language file. Language files are separate embedded JSON resources (e.g. Food.en-US.json) stored alongside the template.
{{t "composition"}}
language query parameter when rendering via the generate/default endpoints.en-US, nl-BE, fr-FR, de-DE, it-IT, pt-PT, es-ES.[key] if the key is not found.{{t "key"}} will always render as [key]. This is expected. Translations are resolved at render time via the generate endpoints.Each language file is a flat key-value JSON file named {TemplateName}.{locale}.json (e.g. Food.en-US.json, Food.fr-FR.json):
{
"composition": "Ingredients",
"nutritionDeclaration": "Nutrition Declaration",
"labelsAndCertifications": "Labels and certifications",
"storageAndConservation": "Storage and conservation",
"feedingInstructions": "Preparation instructions",
"productOrigin": "Product origin",
"alc": "Alc."
}
These files are embedded resources in the application. Adding a new language means adding a new {TemplateName}.{locale}.json file.
{{> partial-name}}
Partials inherit the current context. They can also call other partials (nested).
Create your own via the Partials modal. Useful for reusable sections like nutrition tables, allergen lists, or shared headers/footers. Reference them by name in any template associated with the same retailer.
The source data is a JSON array containing one specification object per product. The template receives the full array as its root context.
{{#each this}}...{{/each}}| Path | Type | Description |
|---|---|---|
specificationId | string | Unique specification identifier |
languageCode | string | e.g. "en-US", "fr-FR" |
supplierCompany | object | .companyDisplayName, .companyLegalName |
productInfo.templateType.code | string | "food", "non-food", etc. |
progression.status | string | "inProgress", "completed", etc. |
chapters.labeling)This is where most label data lives. Key sections:
| Section | Path | Key Fields |
|---|---|---|
| Product Info | productInformationSection |
commercialName, legalName, productDescription, netContents[], volumeOfAlcohol |
| Ingredient Lists | ingredientListSection.ingredientLists[] |
originalIngredientList (HTML with bold allergens), modifiedIngredientList |
| Nutrition | nutritionDeclarationSection.nutritionDeclarations[] |
nutrients[] with .nutrient.name, .servings[].roundedValueString, .unitOfMeasure.abbreviation |
| Nutri-Score | nutriscoreSection.nutriscores[] |
nutriscore.grade, nutriscore.totalScore, displayOnPack |
| Claims | claimsSection.claims[] |
claim.claimName, claim.claimType, claim.logo.fileId, sentenceText, displayOnPack |
| Consumer Instructions | consumerInstructionsSection |
storageAndConservation, cookingInstructions, productOriginList, codesAndDates |
| Business Name | businessNameAndAddressSection |
consumerServiceInformation, additionalInformation, healthMarks, packerCodes |
| Marketing Info | additionalMarketingInformationSection |
information.value (HTML) |
| Sorting Instructions | sortingInstructionsSection.sortingStreams[] |
sortingStream.translations[], countries[].components |
displayOnPack PatternMost labeling fields have a displayOnPack boolean. Always check it before rendering:
{{#if CommercialName.DisplayOnPack}}
<h2>{{CommercialName.CommercialName}}</h2>
{{/if}}
{{#with NutritionDeclarationSection}}
{{#each NutritionDeclarations}}
<table class="nutrition-table">
<thead>
<tr>
<th></th>
{{#each ServingDefinitions}}
<th>Per {{Size.Value}} {{Size.UnitOfMeasure.Abbreviation}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each Nutrients}}
{{#if DisplayToConsumer}}
<tr>
<td>{{Nutrient.Name}}</td>
{{#each Servings}}
<td>{{RoundedValueString}} {{../UnitOfMeasure.Abbreviation}}</td>
{{/each}}
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
{{/each}}
{{/with}}
{{#each Chapters.Production}}
{{#with AllergenSection}}
<strong>Contains:</strong>
{{#each RawMaterialAllergens}}
{{Allergen.Name}}{{#unless @last}}, {{/unless}}
{{/each}}
{{#if CrossContamination.length}}
<br/><em>May contain:</em>
{{#each CrossContamination}}
{{#unless ControlledRisk}}
{{Allergen.Name}}{{#unless @last}}, {{/unless}}
{{/unless}}
{{/each}}
{{/if}}
{{/with}}
{{/each}}
{{#each NetContents}}
{{#if DisplayOnPack}}{{#if Value}}
<div class="net-wt-line">
<span class="net-wt">{{Value}}{{UnitOfMeasure.Abbreviation}}{{#if UnitOfMeasure.Name}} ({{UnitOfMeasure.Name}}){{/if}}</span>
{{#if EMark}}<span class="emark">℮</span>{{/if}}
</div>
{{/if}}{{/if}}
{{/each}}
{{#each NutriscoreSection.Nutriscores}}
{{#if DisplayOnPack}}
{{{nutriscore-img Nutriscore.Grade}}}
{{/if}}
{{/each}}
{{#with Chapters.Labeling.ClaimsSection}}
{{#if Claims}}
<div class="claims-logos">
{{#each Claims}}
{{#if DisplayOnPack}}
{{#if Claim.Logo.FileId}}
{{{dms-img Claim.Logo.FileId Claim.ClaimName}}}
{{/if}}
{{/if}}
{{/each}}
</div>
<div class="claims-sentences">
{{#each Claims}}
{{#if DisplayOnPack}}
{{#unless Claim.Logo.FileId}}
{{#if SentenceText}}
<div>{{{SentenceText}}}</div>
{{/if}}
{{/unless}}
{{/if}}
{{/each}}
</div>
{{/if}}
{{/with}}
SentenceText contains the resolved claim sentence for the current language.Label Template Tool — Built with Handlebars.Net