Extbase plugins
Handlebars integrates Handlebars rendering into the Extbase
MVC stack. It implements
\TYPO3\ and
is wired globally, so every Extbase controller that goes through the standard
view factory mechanism automatically benefits from it without any code changes.
When the factory detects an Extbase request it reads the
handlebars key from the plugin's TypoScript configuration and
returns a
Handlebars. If no
handlebars key is present
and the controller does not extend
Handlebars, the factory
falls back to the Fluid view.
TypoScript configuration
Per-plugin Handlebars configuration lives under the
handlebars
key in the plugin's TypoScript configuration:
plugin.tx_myextension_myplugin {
handlebars {
default {
templateRootPaths.10 = EXT:my_extension/Resources/Private/Templates/Handlebars
partialRootPaths.10 = EXT:my_extension/Resources/Private/Partials/Handlebars
}
}
}
Resolution keys
The
handlebars array supports four keys, resolved and merged
from least to most specific so that narrower entries override broader ones:
| Key | Applies to |
|---|---|
default | All controllers in the plugin |
<Controller | One controller, all actions |
<Controller | One controller, one action |
<Controller | Controller matched by fully-qualified class name |
plugin.tx_myextension_myplugin {
handlebars {
default {
templateRootPaths.10 = EXT:my_extension/Resources/Private/Templates/Handlebars
partialRootPaths.10 = EXT:my_extension/Resources/Private/Partials/Handlebars
}
Blog {
templateRootPaths.20 = EXT:my_extension/Resources/Private/Templates/Blog
}
Blog::list {
templateName = @blog-list
}
}
}
The controller alias matches the value registered in
Extension. For the example above,
Blog would typically have alias
Blog.
Properties
Each resolution key accepts the same properties as a HANDLEBARSTEMPLATE content object:
| Property | Type | Description |
|---|---|---|
template | string | Template name or @-prefixed flat name.
Defaults to
<Controller. |
format | string | File extension. Defaults to hbs. |
template | array | Additional template root paths. |
partial | array | Additional partial root paths. |
variables | array | Extra variables passed to the template. |
Default template name
When no
template is configured, the factory derives one
automatically from the controller alias and action name:
<ControllerAlias>/<actionName>
For
Blog with alias
Blog this
resolves to Blog/ under the configured template root paths.
HandlebarsController
For controllers you own, extend
\CPSIT\ instead of
Action. This guarantees Handlebars rendering even when no
handlebars TypoScript key is present — the factory always returns
a
Handlebars for these controllers:
namespace Vendor\MyExtension\Controller;
use CPSIT\Typo3Handlebars\Controller\HandlebarsController;
use Psr\Http\Message\ResponseInterface;
final class BlogController extends HandlebarsController
{
public function listAction(): ResponseInterface
{
$this->view->assign('posts', $this->postRepository->findAll());
return $this->htmlResponse($this->renderView());
}
}
Fluid fallback
During an incremental migration you may need to keep some actions on Fluid
while others are already on Handlebars. Call
delegate on the
view to hand off to the underlying Fluid view for that action:
public function legacyAction(): ResponseInterface
{
$this->view->assign('items', $this->repository->findAll());
$content = $this->view instanceof HandlebarsView
? $this->view->delegateRendering()
: $this->view->render();
return $this->htmlResponse((string)$content);
}
See also
- HANDLEBARSTEMPLATE content object — full property reference for
HANDLEBARSTEMPLATE - Template paths — how template and partial root paths are collected and prioritised