---
title: "Concept mapping"
manual: "Handlebars"
version: "main"
permalink: "https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-concept-mapping@main"
source: "Guides/MigrationFromFluid/ConceptMapping.rst"
rendered: "2026-09-29T09:05:57+00:00"
---

# Concept mapping {#migration-from-fluid-concept-mapping}

Fluid and Handlebars share the same goal — separating presentation from logic —
but take different philosophical stances on *how much* the template language
itself should do. Understanding this difference up front makes the rest of the
migration straightforward.

-   [The logic-less philosophy](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:the-logic-less-philosophy@main)
-   [Concept-by-concept mapping](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:concept-by-concept-mapping@main)
-   [Things Handlebars does not have](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:things-handlebars-does-not-have@main)

## The logic-less philosophy {#migration-from-fluid-concept-philosophy}

Fluid templates can contain complex expressions: inline ViewHelper chaining,
boolean operators, type-coercing comparisons, and dynamic dispatch to arbitrary
PHP classes. This power comes at the cost of templates that are hard to read
outside of a PHP context.

Handlebars is explicitly "logic-less". Templates may only output values, iterate
over arrays, and branch on truthiness. All other logic must live in a named
**helper** — a PHP callable registered with the renderer. This constraint keeps
templates readable by designers and front-end developers who do not know PHP,
and it shifts complexity to a layer that can be unit-tested cleanly.

## Concept-by-concept mapping {#migration-from-fluid-concept-table}

The table below maps every major Fluid concept to its Handlebars equivalent.
Detailed examples for each row are given in the linked pages.

| Fluid | Handlebars | See |
| --- | --- | --- |
| `{variable}` | `{{variable}}` (HTML-escaped) | [Template syntax](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-syntax@main) |
| `{variable -> f:format.raw()}` | `{{{variable}}}` (triple-stash, raw) | [Template syntax](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-syntax@main) |
| `<f:if condition="...">`, `<f:else>` | `{{#if ...}}`, `{{else}}`, `{{#unless}}` | [Template syntax](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-syntax@main) |
| `<f:for each="{list}" as="item">` | `{{#each list}}`, `{{this}}`, `@index` | [Template syntax](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-syntax@main) |
| `<f:render partial="Name" />` | `{{> Name}}` | [Template syntax](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-syntax@main) |
| `<f:render partial="Name" arguments="{key: value}" />` | `{{> Name key=value}}` | [Template syntax](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-syntax@main) |
| `<f:layout name="Default" />` | `{{#extend "default"}} … {{/extend}}` | [Layouts and partials](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-layouts@main) |
| `<f:render section="Main">` (in layout) | `{{#block "main"}} … {{/block}}` | [Layouts and partials](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-layouts@main) |
| `<f:section name="Main">` (in template) | `{{#content "main"}} … {{/content}}` | [Layouts and partials](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-layouts@main) |
| ViewHelper class | Helper callable + `#[AsHelper]` attribute | [Helpers](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-helpers@main) |
| `<f:translate key="..." />` | Custom `translate` helper | [Helpers](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-helpers@main) |
| `<f:format.date format="..." />` | Custom `formatDate` helper | [Helpers](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-helpers@main) |
| `FLUIDTEMPLATE` content object | `HANDLEBARSTEMPLATE` content object | [Gradual migration](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-gradual@main) |
| Extbase `ActionController` | `HandlebarsController` (`assign()` still works) | [Extbase plugins](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:extbase-plugin@main) |
| `plugin.tx_myext.view.templateRootPaths` | `plugin.tx_handlebars.view.templateRootPaths` | [Template paths](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:template-paths@main) |

> [!NOTE]
> **See also**
>
> [Handlebars Language Guide](https://handlebarsjs.com/guide/) to explore
> more available language features.

## Things Handlebars does not have {#migration-from-fluid-concept-no-equivalent}

Some Fluid features have no direct equivalent and require a different approach:

-   ****Inline ViewHelper chains****

    Fluid allows `{value -> f:format.trim() -> f:format.upper()}`. In
    Handlebars, compose the same logic in a single helper that applies
    both transformations.

-   ****Arithmetic and boolean operators in templates****

    Fluid supports `{a + b}` and `{a && b}` in some contexts. In
    Handlebars, compute the result in a data processor or a helper and expose it
    as a plain variable.

-   ****Type-aware comparisons****

    `<f:if condition="{count} > 0">` works in Fluid because it parses the
    expression. Handlebars `{{#if count}}` only tests truthiness —
    `0` and the empty string are falsy, everything else is truthy. Write a
    helper if you need a numeric comparison.

-   ****Named format strings in the template****

    Fluid's `<f:format.*>` ViewHelpers apply a PHP function to a value.
    Replace each one with a small helper whose name describes the transformation
    (e.g., `{{formatDate date format="d.m.Y"}}`).

> [!NOTE]
> The extension ships a `viewHelper` bridge helper that lets you
> call any registered Fluid ViewHelper from a Handlebars template without
> writing a wrapper. This is intended as a temporary aid during migration;
> see [Fluid ViewHelper bridge](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration-from-fluid-helpers-bridge@main) for details.
