Layouts and partials 

Fluid's layout system — <f:layout>, <f:section>, and <f:render section="..."> — is one of the first things developers look for when switching template engines. EXT:handlebars ships an equivalent mechanism implemented as the extend, block, and content helpers, modelled after the handlebars-layouts convention.

How the systems compare 

Fluid uses a push model: a child template declares which layout it inherits and then pushes named sections into the layout's named slots. Handlebars uses the same model, but the building blocks are ordinary helpers rather than dedicated language constructs.

Fluid Handlebars
<f:layout name="Default" /> {{#extend "default"}} … {{/extend}}
<f:render section="Main"> (in layout) {{#block "main"}} … {{/block}}
<f:section name="Main"> (in template) {{#content "main"}} … {{/content}}

The content helper supports an optional mode hash argument (replace / append / prepend) that controls how the child's content is merged with the layout block's default. replace is the default and matches Fluid's behaviour.

Side-by-side example 

Layout file — Fluid:

EXT:my_extension/Resources/Private/Layouts/Default.html
<!DOCTYPE html>
<html>
<head>
    <f:render section="Head" optional="true" />
</head>
<body>
    <header>
        <f:render section="Header" />
    </header>
    <main>
        <f:render section="Main" />
    </main>
    <footer>
        <f:render section="Footer" optional="true" />
    </footer>
</body>
</html>
Copied!

Layout file — Handlebars:

EXT:my_extension/Resources/Private/Partials/default.hbs
<!DOCTYPE html>
<html>
<head>
    {{#block "head"}}{{/block}}
</head>
<body>
    <header>
        {{#block "header"}}{{/block}}
    </header>
    <main>
        {{#block "main"}}{{/block}}
    </main>
    <footer>
        {{#block "footer"}}{{/block}}
    </footer>
</body>
</html>
Copied!

Child template — Fluid:

EXT:my_extension/Resources/Private/Templates/MyElement.html
<f:layout name="Main" />

<f:section name="Head">
    <title>{header}</title>
</f:section>

<f:section name="Header">
    <h1>{header}</h1>
</f:section>

<f:section name="Main">
    <p>{bodytext}</p>
</f:section>
Copied!

Child template — Handlebars:

EXT:my_extension/Resources/Private/Templates/my-element.hbs
{{#extend "Main"}}
    {{#content "head"}}
        <title>{{header}}</title>
    {{/content}}

    {{#content "header"}}
        <h1>{{header}}</h1>
    {{/content}}

    {{#content "main"}}
        <p>{{bodytext}}</p>
    {{/content}}
{{/extend}}
Copied!

Default content in blocks 

A {{#block}} can hold default markup that is used verbatim when the child provides no matching {{#content}} for that slot. This is the equivalent of Fluid's optional="true" on <f:render section="..."> combined with a fallback in the layout.

EXT:my_extension/Resources/Private/Partials/Main.hbs
<footer>
    {{#block "footer"}}
        <p>&copy; {{year}} My Site</p>
    {{/block}}
</footer>
Copied!

A child template that does not declare a {{#content "footer"}} block will render the default copyright line automatically.

Appending and prepending content 

The mode argument lets a child add to a block rather than replace it. This has no direct Fluid equivalent and is often used for accumulating <script> or <link> tags:

EXT:my_extension/Resources/Private/Templates/my-element.hbs
{{#extend "Main"}}
    {{#content "head" mode="append"}}
        <link rel="stylesheet" href="/assets/my-element.css">
    {{/content}}

    {{#content "main"}}{{/content}}
{{/extend}}
Copied!

Using partials without a layout 

Not every template needs a full layout. Reusable snippets that were Fluid partials map directly to Handlebars partials with no extra ceremony — just create a .hbs file in the partial root path and include it with {{> Name}}.