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

# Helpers {#migration-from-fluid-helpers}

Fluid ViewHelpers and Handlebars helpers serve the same role: they bring PHP
logic into templates. The implementation model is different enough to warrant a
dedicated page.

-   [ViewHelpers vs. Helpers](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:viewhelpers-vs-helpers@main)
-   [Porting an inline ViewHelper](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:porting-an-inline-viewhelper@main)
-   [Porting a block / wrapping ViewHelper](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:porting-a-block-wrapping-viewhelper@main)
-   [Common ViewHelper equivalents](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:common-viewhelper-equivalents@main)
-   [Fluid ViewHelper bridge](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:fluid-viewhelper-bridge@main)

## ViewHelpers vs. Helpers {#migration-from-fluid-helpers-comparison}

A Fluid ViewHelper is a PHP class that implements
`\TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper`. Arguments are
declared via `initializeArguments()` and the class is resolved by its
namespace prefix (e.g., `f:`, `myext:`).

A Handlebars helper is any PHP callable registered via the `#[AsHelper]`
attribute. Arguments reach the callable either as named hash arguments
(`name=value` pairs after the helper name) or as positional arguments
(bare values in order). There is no argument declaration step — the method
signature is the contract.

| Fluid ViewHelper | Handlebars helper |
| --- | --- |
| Class extending `AbstractViewHelper` | Any class / method / callable |
| Namespace prefix in template | Plain identifier string |
| `initializeArguments()` | Method parameters |
| `renderChildren()` | `$options->fn($options->scope)` |
| Registered via namespace import | `#[AsHelper('name')]` attribute |

## Porting an inline ViewHelper {#migration-from-fluid-helpers-inline}

Inline ViewHelpers that transform a single value (like `<f:format.date>`)
are the most common case. The Handlebars equivalent is a helper that receives the
value as a positional argument and returns the formatted string.

**Fluid:**

```html
<f:format.date format="d.m.Y">{date}</f:format.date>

{date -> f:format.date(format: 'd.m.Y')}
```

**Handlebars:**

```handlebars
{{formatDate date format="d.m.Y"}}
```

**Helper implementation:**

**EXT:my_extension/Classes/Renderer/Helper/FormatDateHelper.php**

```php
namespace Vendor\Extension\Renderer\Helper;

use CPSIT\Typo3Handlebars\Attribute\AsHelper;
use DevTheorem\Handlebars\HelperOptions;

#[AsHelper('formatDate')]
final readonly class FormatDateHelper
{
    public function __invoke(HelperOptions $options, ?\DateTimeInterface $date = null): ?string
    {
        $format = is_string($options->hash['format'] ?? null)
            ? $options->hash['format']
            : 'd.m.Y';

        return $date?->format($format);
    }
}
```

## Porting a block / wrapping ViewHelper {#migration-from-fluid-helpers-block}

ViewHelpers that wrap inner content (block ViewHelpers) correspond to
Handlebars *block helpers*. The inner content is rendered via
`$options->fn($options->scope)` and the inverse (`{{else}}`)
branch via `$options->inverse($options->scope)`.

**Fluid:**

```html
<myext:ifGranted role="ADMIN">
    <a href="/admin">Admin panel</a>
</myext:ifGranted>
```

**Handlebars:**

```handlebars
{{#ifGranted role="ADMIN"}}
    <a href="/admin">Admin panel</a>
{{/ifGranted}}
```

**Helper implementation:**

**EXT:my_extension/Classes/Renderer/Helper/IfGrantedHelper.php**

```php
namespace Vendor\Extension\Renderer\Helper;

use CPSIT\Typo3Handlebars\Attribute\AsHelper;
use DevTheorem\Handlebars\HelperOptions;
use Vendor\Extension\Security\AccessChecker;

#[AsHelper('ifGranted')]
final readonly class IfGrantedHelper
{
    public function __construct(
        private AccessChecker $accessChecker,
    ) {}

    public function __invoke(HelperOptions $options): string
    {
        $role = $options->hash['role'] ?? '';

        if ($this->accessChecker->isGranted((string)$role)) {
            return (string)$options->fn($options->scope);
        }

        return (string)$options->inverse($options->scope);
    }
}
```

## Common ViewHelper equivalents {#migration-from-fluid-helpers-common}

The table below lists frequently used Fluid ViewHelpers and how to handle them
in Handlebars templates.

| Fluid ViewHelper | Handlebars approach |
| --- | --- |
| `f:if` | Built-in `{{#if}}` / `{{#unless}}` |
| `f:for` | Built-in `{{#each}}` |
| `f:alias` | Built-in `{{#with}}` |
| `f:format.raw` | Triple-stash `{{{variable}}}` |
| `f:format.htmlspecialchars` | Default `{{variable}}` (always escapes) |
| `f:format.date` | Custom `formatDate` helper |
| `f:format.number` | Custom `formatNumber` helper |
| `f:translate` | Custom `translate` helper (use TYPO3 API inside) |
| `f:uri.page`, `f:link.*` | Custom URI helper (use `UriBuilder` inside) |
| `f:image` | Custom image helper (use TYPO3 image API inside) |
| `f:render partial="…"` | `{{> PartialName}}` or `{{render "PartialName"}}` |
| `f:debug` | Built-in `{{debug}}` helper |

## Fluid ViewHelper bridge {#migration-from-fluid-helpers-bridge}

As a temporary migration aid, the extension ships a `viewHelper`
helper that invokes any registered Fluid ViewHelper directly from a Handlebars
template. This lets you use existing ViewHelpers without writing a wrapper immediately.

```handlebars
{{viewHelper "f:format.date" date=someDate format="d.m.Y"}}

{{viewHelper "myext:widget.paginate" objects=items as="pagedItems"}}

{{#viewHelper "myext:security.ifGranted" role="ADMIN"}}
    <a href="/admin">Admin panel</a>
{{/viewHelper}}
```

To use ViewHelpers from a custom namespace, register the namespace first with
`viewHelperNamespace`:

```handlebars
{{viewHelperNamespace "tx" "https://typo3.org/ns/Vendor/Extension/ViewHelpers"}}
{{viewHelper "tx:myHelper" someArg=value}}
```

> [!IMPORTANT]
> The `viewHelper` helper is intended as a **short-term escape
> hatch** during migration, not as a permanent pattern. It carries the overhead
> of bootstrapping a Fluid rendering context for every invocation and relies on
> internal Fluid APIs that may change. Replace it with a proper Handlebars
> helper once the migration for the affected template is complete.

> [!NOTE]
> **See also**
>
> -   [Custom helpers](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:custom-helpers@main) — full reference for implementing and registering
>     Handlebars helpers
> -   [Built-in helpers](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:templates-helpers@main) — all helpers shipped with the extension
