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.