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 

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 :php: #[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 

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:

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

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

Handlebars:

{{formatDate date format="d.m.Y"}}
Copied!

Helper implementation:

EXT:my_extension/Classes/Renderer/Helper/FormatDateHelper.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);
    }
}
Copied!

Porting a block / wrapping ViewHelper 

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:

<myext:ifGranted role="ADMIN">
    <a href="/admin">Admin panel</a>
</myext:ifGranted>
Copied!

Handlebars:

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

Helper implementation:

EXT:my_extension/Classes/Renderer/Helper/IfGrantedHelper.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);
    }
}
Copied!

Common ViewHelper equivalents 

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 

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.

{{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}}
Copied!

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

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