Writing templates
Templates are plain .hbs files using the standard
Handlebars syntax: expressions, block
helpers such as { and {, 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.
template resolves to
Blog/ in one of the template root paths, and
{ to Components/ 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
}
{{> @card}}
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 --}}
Partials
Partials are included with the standard { 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}}
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
{. A block may contain default content that is used
if no template fills the slot:
<main>
{{#block "main"}}{{/block}}
</main>
<footer>
{{#block "footer"}}
<p>© My Site</p>
{{/block}}
</footer>
A template wraps its markup in { and fills slots with
{:
{{#extend "default"}}
{{#content "main"}}
<h1>{{header}}</h1>
{{/content}}
{{/extend}}
By default, { replaces the block's default content.
Pass mode="append" or mode="prepend" to add to it
instead.
Note
Layouts are resolved as partials, so layout files must be placed in one of the configured partial root paths.
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. {
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}}
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}}
join
Joins all given values into a string. Values that cannot be converted to a string are skipped:
{{join firstName lastName separator=" "}}
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)}}
debug
Dumps a value using Extbase's
Debugger. Without argument, the
current context is dumped:
{{debug}}
{{debug item title="Current item" maxDepth=3}}
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"}}
Debugging tips
- Use
{to inspect the available variables.{debug}} - 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.