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 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
The following classes and interfaces have been removed and have no replacement:
\CPSIT\(interface)Typo3Handlebars\ Data Processing\ Data Processor \CPSIT\Typo3Handlebars\ Data Processing\ Abstract Data Processor \CPSIT\(interface)Typo3Handlebars\ Data\ Data Provider \CPSIT\(interface)Typo3Handlebars\ Data\ Response\ Provider Response \CPSIT\(interface)Typo3Handlebars\ Presenter\ Presenter \CPSIT\Typo3Handlebars\ Presenter\ Abstract Presenter \CPSIT\Typo3Handlebars\ Data Processing\ Simple Processor
The
handlebars. service tag has also been removed.
TypoScript entry point
Before: Each content element was routed to a
Data class via
a
USER content object:
tt_content.header = USER
tt_content.header.userFunc = Vendor\Extension\DataProcessing\HeaderProcessor->process
After: Use
HANDLEBARSTEMPLATE directly:
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)
Before: Data was prepared in a
Data class and returned as a
Provider object, which the
Presenter then passed to the
renderer.
After: Data is prepared entirely in TypoScript:
- Simple field values: use
variableswith content objects such asTEXT,FILES, etc. - Database relations and menus: use standard TYPO3
dataprocessors (e.g.,Processing database-,query menu). - Per-record variable processing inside a loop: use process-variables.
Template selection (Presenter → templateName)
Before: The
Presenter called
$this->renderer->render.
After: The template is declared in TypoScript:
tt_content.my_element {
templateName = MyElement
}
For conditional template selection, use stdWrap on
template:
tt_content.my_element {
templateName = MyElement
templateName.override.if {
isTrue.field = tx_myext_variant
value = special
}
templateName.override = MyElementSpecial
}
Helper registration
Before: Helpers were registered via Services. tags:
services:
Vendor\Extension\Renderer\Helper\GreetHelper:
tags:
- name: handlebars.helper
identifier: 'greet'
method: 'greetById'
After: Use the
# attribute directly on the class or method:
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. tag approach still works and can be used if you
cannot modify the helper class (e.g., a third-party class).
Template path configuration
Template path configuration via Services. and TypoScript remains
unchanged. In addition, paths can now also be set per-content-object directly
in
HANDLEBARSTEMPLATE:
tt_content.textmedia = HANDLEBARSTEMPLATE
tt_content.textmedia {
templateRootPaths.10 = EXT:my_extension/Resources/Private/Templates
partialRootPaths.10 = EXT:my_extension/Resources/Private/Partials
}
See also
Template paths for the full configuration reference.