TemplateResolver
Implement the \CPSIT\Typo3Handlebars\Renderer\Template\TemplateResolver interface to change how template and partial names are resolved to absolute file paths — for example to support a different directory layout, an additional file extension, or a database-driven path lookup.
The extension ships two implementations:
\CPSIT\ (the
default) and
\CPSIT\.
\CPSIT\ implements
supports and provides protected helpers for normalizing root paths and
resolving filenames with
EXT:
syntax. Extending it keeps
implementations concise.
-
interface
TemplateResolver -
- Fully qualified name
-
\CPSIT\Typo3Handlebars\ Renderer\ Template\ Template Resolver
supports(string $fileExtension)-
Return
trueif this resolver handles the given file extension.- param string $fileExtension
-
File extension without leading dot.
- returntype
-
bool
FlatTemplateResolver
Flat is the default implementation. It scans all
configured root paths recursively and builds an in-memory map of every
template file, keyed by its bare filename (without directory). A lookup
therefore succeeds regardless of where in the directory tree the file lives.
Template and partial names must be prefixed with @ to trigger flat
resolution, optionally with a --<variant> suffix that falls back to
the base name (see Referencing templates and partials for usage). A name without the
prefix is passed directly to
Handlebars (see below).
When the same filename exists under multiple root paths, the higher-priority root path wins (see Template paths). Within a single root path, files are sorted by name and the first occurrence is used, matching Fractal's uniqueness guarantee.
HandlebarsTemplateResolver
Handlebars resolves template and partial names as
paths relative to the configured root paths. Given the name Blog/,
it searches each root path (highest priority first) for a matching file —
for example Blog/.
This resolver is used as the fallback inside
Flat
for any name that does not start with @, so both resolution strategies
are active at the same time.
Example implementation
namespace Vendor\Extension\Renderer\Template;
use CPSIT\Typo3Handlebars\Exception;
use CPSIT\Typo3Handlebars\Renderer\Template\BaseTemplateResolver;
use CPSIT\Typo3Handlebars\Renderer\Template\TemplatePaths;
final readonly class MyTemplateResolver extends BaseTemplateResolver
{
public function __construct(
private TemplatePaths $templatePaths,
) {}
public function resolveTemplatePath(string $templatePath, ?string $format = null): string
{
[$templateRootPaths] = $this->resolveTemplatePaths($this->templatePaths);
foreach (array_reverse($templateRootPaths) as $rootPath) {
$filename = $this->resolveFilename($templatePath, $rootPath, $format ?? 'hbs');
if (is_file($filename)) {
return $filename;
}
}
throw new Exception\TemplatePathIsNotResolvable($templatePath);
}
public function resolvePartialPath(string $partialPath, ?string $format = null): string
{
[, $partialRootPaths] = $this->resolveTemplatePaths($this->templatePaths);
foreach (array_reverse($partialRootPaths) as $rootPath) {
$filename = $this->resolveFilename($partialPath, $rootPath, $format ?? 'hbs');
if (is_file($filename)) {
return $filename;
}
}
throw new Exception\PartialPathIsNotResolvable($partialPath);
}
}
Wiring the implementation
Register the custom resolver as the implementation of the
Template interface in your extension's Services.:
services:
CPSIT\Typo3Handlebars\Renderer\Template\TemplateResolver:
alias: Vendor\Extension\Renderer\Template\MyTemplateResolver