Writing templates 

Templates are plain .hbs files using the standard Handlebars syntax: expressions, block helpers such as {{#if}} and {{#each}}, partials and comments all work as documented there. This page covers what the extension adds on top: how template names are resolved, how to build layouts, and which helpers are available out of the box.

Referencing templates and partials 

Templates and partials are referenced by name, without the .hbs file extension. They are looked up in the configured template and partial root paths. Two addressing styles are supported.

Directory-relative names 

A name without prefix is resolved relative to the root paths, just like in Fluid. templateName = Blog/List resolves to Blog/List.hbs in one of the template root paths, and {{> Components/Card}} to Components/Card.hbs in one of the partial root paths.

Flat names 

A name prefixed with @ is looked up by its bare filename, regardless of the subdirectory the file lives in:

tt_content.tx_myext_teaser = HANDLEBARSTEMPLATE
tt_content.tx_myext_teaser {
    # Finds e.g. Components/Molecules/teaser.hbs
    templateName = @teaser
}
Copied!
{{> @card}}
Copied!

If the same filename exists in multiple root paths, the root path with the higher priority wins. This follows the Fractal naming convention, so a Fractal component library can be used as template source without changes.

Appending --<variant> selects a named variant. If no dedicated file exists for the variant, the base name is used instead:

{{> @card--highlighted}}   {{!-- falls back to @card if not found --}}
Copied!

Partials 

Partials are included with the standard {{> name}} syntax. Without further arguments, the partial receives the current context. Pass a different context as positional argument and/or single values as hash arguments:

{{> @card}}
{{> @card item}}
{{> @card title=item.title image=item.image}}
Copied!

The render helper is an alternative that allows passing and merging contexts explicitly, see render.

Layouts 

Layouts are built with the extend, block and content helpers, modelled after handlebars-layouts. A layout is an ordinary partial that declares named slots with {{#block}}. A block may contain default content that is used if no template fills the slot:

EXT:my_sitepackage/Resources/Private/Partials/Handlebars/default.hbs
<main>
    {{#block "main"}}{{/block}}
</main>
<footer>
    {{#block "footer"}}
        <p>&copy; My Site</p>
    {{/block}}
</footer>
Copied!

A template wraps its markup in {{#extend}} and fills slots with {{#content}}:

EXT:my_sitepackage/Resources/Private/Templates/Handlebars/my-element.hbs
{{#extend "default"}}
    {{#content "main"}}
        <h1>{{header}}</h1>
    {{/content}}
{{/extend}}
Copied!

By default, {{#content}} replaces the block's default content. Pass mode="append" or mode="prepend" to add to it instead.

Built-in helpers 

Next to the helpers built into Handlebars itself (if, unless, each, with, lookup, log), the extension registers the following helpers. To add your own, see Custom helpers.

extend, block, content 

Build layouts, see Layouts. {{#extend}} accepts an optional context as second argument and hash arguments, which are merged into the context passed to the layout.

render 

Renders a partial. The first argument is the partial name, the optional second argument a custom context:

{{render "@card"}}
{{render "@card" item}}
{{render "@card" item merge=true}}
Copied!

Without custom context, the partial receives the root variable named like the partial itself (e.g. @card), if present. This matches how Fractal provides component contexts. With merge=true, the custom context is merged into this default context instead of replacing it.

get 

Reads a property path from an object or array. Unlike plain dot notation, it supports getter methods and dynamic keys. Paths are resolved the same way as variable paths in Fluid templates:

{{get post "category.title"}}
{{get object dynamicKey}}
Copied!

join 

Joins all given values into a string. Values that cannot be converted to a string are skipped:

{{join firstName lastName separator=" "}}
Copied!

merge 

Merges arrays recursively, with later arrays overriding earlier ones. Hash arguments are merged last. Mostly used as a subexpression to build a context for a partial:

{{> @card (merge item highlighted=true)}}
Copied!

debug 

Dumps a value using Extbase's DebuggerUtility . Without argument, the current context is dumped:

{{debug}}
{{debug item title="Current item" maxDepth=3}}
Copied!

viewHelper, viewHelperNamespace 

Invokes a Fluid ViewHelper. This is meant as a temporary aid when migrating from Fluid:

{{viewHelper "f:format.date" date=someDate format="d.m.Y"}}
Copied!

Debugging tips 

  • Use {{debug}} to inspect the available variables.
  • Enable rendering.strictMode during development to get an exception for missing variables instead of empty output.
  • Compiled templates are cached. Flush caches if template changes don't show up.