Handlebars Templating Standards
The "Logic-less" Philosophy
- Data Preparation: Templates should strictly DISPLAY data. All filtering, sorting, or complex math MUST happen in the application code (Controller/Service) before the data reaches the template.
- Avoid Spaghettis: If you need more than two nested
{{#if}}or{{#each}}blocks, consider refactoring the data structure or creating a custom helper.
Syntax & Helpers
- Escaping:
- Default {{value}} is safe and escapes HTML characters. - Use {{{value}}} (triple-stash) ONLY for trusted HTML strings (e.g., pre-sanitized content).
- Custom Helpers:
- Do not write complex inline logic. Instead of {{#if (eq (mod index 2) 0)}}, create a helper {{#if (isEven index)}} or, better yet, pre-calculate isEven in the data model. - Register helpers for formatting dates, currencies, and translation.
Component Architecture (Partials)
- Atomic Design: Break complex UIs into small files in the
partials/directory.
- Naming convention: _card.hbs, _navbar.hbs.
- Context Passing:
- Explicit Context: {{> myPartial specificData}} is preferred over implicit context inheritance. - Block Partials: Use {{#> layout}}... {{/layout}} for wrapping content (like slots).
Troubleshooting
- Missing Properties: Handlebars fails silently on undefined properties. Ensure your data object structure strictly matches the template expectations.
- Prototypes: If using Mongoose/ORMs, convert documents to Plain Old JavaScript Objects (POJOs) (e.g.,
.lean()or.toJSON()) before passing to Handlebars to avoid prototype access issues.