---
title: "Migration"
manual: "Handlebars"
version: "main"
permalink: "https://docs.typo3.org/permalink/cpsit/typo3-handlebars:migration@main"
source: "Migration/Index.rst"
rendered: "2026-09-29T09:05:57+00:00"
---

# Migration {#migration}

This page lists required migration steps when upgrading to a new major version
of the extension.

## Version 1.0.0 {#version-1-0-0}

Version 1.0.0 replaces the previous PHP-class rendering model (DataProcessor /
DataProvider / Presenter) with the `HANDLEBARSTEMPLATE` content
object. All rendering configuration moves to TypoScript; custom PHP classes are
no longer the entry point.

### Removed classes and interfaces {#migration-1-removed-classes}

The following classes and interfaces have been removed and have no replacement:

-   `\CPSIT\Typo3Handlebars\DataProcessing\DataProcessor` (interface)
-   `\CPSIT\Typo3Handlebars\DataProcessing\AbstractDataProcessor`
-   `\CPSIT\Typo3Handlebars\Data\DataProvider` (interface)
-   `\CPSIT\Typo3Handlebars\Data\Response\ProviderResponse` (interface)
-   `\CPSIT\Typo3Handlebars\Presenter\Presenter` (interface)
-   `\CPSIT\Typo3Handlebars\Presenter\AbstractPresenter`
-   `\CPSIT\Typo3Handlebars\DataProcessing\SimpleProcessor`

The `handlebars.processor` service tag has also been removed.

### TypoScript entry point {#migration-1-typoscript-entry-point}

**Before:** Each content element was routed to a `DataProcessor` class via
a `USER` content object:

```typoscript
tt_content.header = USER
tt_content.header.userFunc = Vendor\Extension\DataProcessing\HeaderProcessor->process
```

**After:** Use `HANDLEBARSTEMPLATE` directly:

```typoscript
tt_content.header = HANDLEBARSTEMPLATE
tt_content.header {
    templateName = Header

    variables {
        header = TEXT
        header.field = header

        subheader = TEXT
        subheader.field = subheader
    }
}
```

### Data preparation (DataProvider → variables / dataProcessing) {#migration-1-data-preparation}

**Before:** Data was prepared in a `DataProvider` class and returned as a
`ProviderResponse` object, which the `Presenter` then passed to the
renderer.

**After:** Data is prepared entirely in TypoScript:

-   Simple field values: use `variables` with content objects
    such as `TEXT`, `FILES`, etc.
-   Database relations and menus: use standard TYPO3 `dataProcessing`
    processors (e.g., `database-query`, `menu`).
-   Per-record variable processing inside a loop: use [process-variables](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:data-processor-process-variables@main).

### Template selection (Presenter → templateName) {#migration-1-template-selection}

**Before:** The `Presenter` called `$this->renderer->render('path/to/template', $data)`.

**After:** The template is declared in TypoScript:

```typoscript
tt_content.my_element {
    templateName = MyElement
}
```

For conditional template selection, use stdWrap on `templateName`:

```typoscript
tt_content.my_element {
    templateName = MyElement
    templateName.override.if {
        isTrue.field = tx_myext_variant
        value = special
    }
    templateName.override = MyElementSpecial
}
```

### Helper registration {#migration-1-helper-registration}

**Before:** Helpers were registered via `Services.yaml` tags:

**Configuration/Services.yaml**

```yaml
services:
  Vendor\Extension\Renderer\Helper\GreetHelper:
    tags:
      - name: handlebars.helper
        identifier: 'greet'
        method: 'greetById'
```

**After:** Use the `#[AsHelper]` attribute directly on the class or method:

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

```php
use CPSIT\Typo3Handlebars\Attribute\AsHelper;
use CPSIT\Typo3Handlebars\Renderer\Helper\Helper;
use DevTheorem\Handlebars\HelperOptions;

#[AsHelper('greet')]
final readonly class GreetHelper implements Helper
{
    public function render(HelperOptions $options): string { /* ... */ }
}
```

The `Services.yaml` tag approach still works and can be used if you
cannot modify the helper class (e.g., a third-party class).

### Debug mode {#migration-1-debug-mode}

The debug mode built into `HandlebarsRenderer` has been removed. Previously,
when TYPO3's `config.debug` flag or
`$GLOBALS['TYPO3_CONF_VARS']['FE']['debug']` was enabled, the renderer
automatically bypassed the template cache and switched the Handlebars compiler
to strict mode (throwing on missing variables instead of silently returning
empty strings).

There is no automatic replacement tied to a debug flag. Use the following
alternatives instead:

-   **Cache bypass:** Disable caching explicitly via
    [TYPO3's caching framework](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/CachingFramework/Index.html#caching) configuration or by
    setting `config.no_cache = 1` during development.
-   **Strict compilation:** Enable
    [rendering.strictMode](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:extension-configuration-rendering-strict-mode@main)
    in the extension configuration. Unlike the previous behavior, this is a
    persistent setting rather than one tied to TYPO3's debug flags.
-   **Strict template validation:** Use the shipped [{{debug}}](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:templates-helpers-debug@main)
    helper inside templates to inspect variable values at render time. For
    programmatic checks, call `Handlebars::precompile()` directly to
    inspect the generated PHP code.

### Template path configuration {#migration-1-template-paths}

No migration needed. Template path configuration via `Services.yaml`
and TypoScript remains unchanged; paths can now additionally be set per
content object (see [Template paths](https://docs.typo3.org/permalink/cpsit/typo3-handlebars:template-paths@main)).
