Label Template Tool — Reference

How to use the tool and the Handlebars template language with custom helpers.

Tool Usage

Authentication

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).

Three-Pane Layout

PanePurpose
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.

Template Management

Partials

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.

Drag & Drop

Drop a .json file onto the Source Data pane to load it instantly.


Template Syntax (Handlebars)

Expressions

SyntaxDescription
{{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

Conditionals

{{#if DisplayOnPack}}
  <p>{{Value}}</p>
{{/if}}

{{#if (equals Status "active")}}
  <span>Active</span>
{{else}}
  <span>Inactive</span>
{{/if}}

Iteration

{{#each Nutrients}}
  <tr>
    <td>{{Nutrient.Name}}</td>
    <td>{{RoundedValueString}} {{UnitOfMeasure.Abbreviation}}</td>
  </tr>
{{/each}}

Context Access

SyntaxMeaning
{{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 Block (Scope Narrowing)

{{#with Chapters.Labeling.ProductInformationSection}}
  <h2>{{CommercialName.CommercialName}}</h2>
  <p>{{LegalName.LegalName}}</p>
{{/with}}

Custom Helpers

equals

Compares two values for strict (case-sensitive) equality. Use inside {{#if}} blocks.

{{#if (equals Status "active")}}Active{{/if}}

contains

Checks whether a string contains a substring.

{{#if (contains IngredientList "milk")}}
  <span class="allergen">Contains milk</span>
{{/if}}

replace

Replaces all occurrences of a substring.

{{replace ProductCode "-" ""}}

join

Concatenates a collection into a single string with a separator.

{{join AllergenNames ", "}}

nutriscore-img

Renders the full Nutri-Score SVG for a grade (A–E).

{{{nutriscore-img NutriscoreGrade}}}
Use triple-stache {{{ }}} because this helper outputs raw HTML (an inline SVG).

dms-img

Renders 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}}}
Use triple-stache {{{ }}} because this helper outputs raw HTML (an <img> tag).
#ArgumentRequiredDescription
1File IDYesA GUID referencing a DMS file
2Alt textNoAlternative text for the image. Defaults to empty string.

lowercase

Converts a string value to lowercase.

{{lowercase UnitOfMeasure.Name}}

uppercase

Converts 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"}}
In Preview mode, translations are not loaded — {{t "key"}} will always render as [key]. This is expected. Translations are resolved at render time via the generate endpoints.

Language File Format

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.


Partials

Using a Partial

{{> partial-name}}

Partials inherit the current context. They can also call other partials (nested).

Custom Partials

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.


Source Data Structure

The source data is a JSON array containing one specification object per product. The template receives the full array as its root context.

Since the root is an array, iterate at the top level: {{#each this}}...{{/each}}

Top-Level Properties

PathTypeDescription
specificationIdstringUnique specification identifier
languageCodestringe.g. "en-US", "fr-FR"
supplierCompanyobject.companyDisplayName, .companyLegalName
productInfo.templateType.codestring"food", "non-food", etc.
progression.statusstring"inProgress", "completed", etc.

Labeling Chapter (chapters.labeling)

This is where most label data lives. Key sections:

SectionPathKey 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

The displayOnPack Pattern

Most labeling fields have a displayOnPack boolean. Always check it before rendering:

{{#if CommercialName.DisplayOnPack}}
  <h2>{{CommercialName.CommercialName}}</h2>
{{/if}}

Nutrition Table Example

{{#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}}

Allergen Section (Production Chapter)

{{#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}}

Net Contents & E-Mark

{{#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">&#x212E;</span>{{/if}}
  </div>
{{/if}}{{/if}}
{{/each}}

Nutri-Score

{{#each NutriscoreSection.Nutriscores}}
{{#if DisplayOnPack}}
  {{{nutriscore-img Nutriscore.Grade}}}
{{/if}}
{{/each}}

Claims with Logos

{{#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}}
Claims with a logo render as images; claims without a logo fall back to their sentence text. SentenceText contains the resolved claim sentence for the current language.

Label Template Tool — Built with Handlebars.Net