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 

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 

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
{variable -> f:format.raw()} {{{variable}}} (triple-stash, raw) Template syntax
<f:if condition="...">, <f:else> {{#if ...}}, {{else}}, {{#unless}} Template syntax
<f:for each="{list}" as="item"> {{#each list}}, {{this}}, @index Template syntax
<f:render partial="Name" /> {{> Name}} Template syntax
<f:render partial="Name" arguments="{key: value}" /> {{> Name key=value}} Template syntax
<f:layout name="Main" /> {{#extend "Main"}} … {{/extend}} Layouts and partials
<f:section name="Main"> (in layout) {{#block "main"}} … {{/block}} Layouts and partials
<f:section name="Main"> (in template) {{#content "main"}} … {{/content}} Layouts and partials
ViewHelper class Helper callable + #[AsHelper] attribute Helpers
<f:translate key="..." /> Custom translate helper Helpers
<f:format.date format="..." /> Custom formatDate helper Helpers
Variables from controller assign() TypoScript variables block Gradual migration
plugin.tx_myext.view.templateRootPaths plugin.tx_handlebars.view.templateRootPaths Template paths

Things Handlebars does not have 

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"}}).