intellect-web-development/templator-symfony-bundle
A Symfony bundle that integrates the Templator templating engine into your application, offering simple service configuration and reliable template rendering. It provides a clean, framework-native way to manage dynamic views with minimal setup.
This bundle is a thin Symfony integration layer around the intellect-web-development/templator rendering library (the vendor/package split implies the engine lives outside the bundle and the bundle only wires services, config, and DI). With 0 stars and 0 dependents there is no Flex recipe, no community docs, and no Stack Overflow trail — treat the repository itself as the only source of truth.
New in 1.1.0: Symfony 8 support was added. That is the only advertised change, so the shape of the package is unchanged — but read the constraint delta in composer.json before installing (see Gotchas; a Symfony 8 bump often drops older versions and raises the PHP floor to 8.4).
Minimal setup:
composer require intellect-web-development/templator-symfony-bundle:1.1.0
Because there is almost certainly no Flex recipe, register the bundle manually. On Symfony 5.4+/6+/7+/8 edit config/bundles.php:
return [
// ...
IntellectWebDevelopment\TemplatorSymfonyBundle\TemplatorBundle::class => ['all' => true],
];
(The exact namespace is the first thing to verify — check composer.json autoload.psr-4 and the class name in src/.)
Where to look first, in this order:
composer.json require — confirm 1.1.0 actually installs on your Symfony and PHP version before anything else (composer why-not ... 1.1.0 is the fastest check).README.md — the only usage documentation; expect it to be terse or Russian-language.CHANGELOG.md / git diff of 1.0.x..1.1.0 — the release note is one line, so the diff is the real changelog. See whether it touched only composer.json or also the DI extension.src/*Bundle.php — confirms the bundle class name, the config alias (getContainerExtension() / getAlias()), and whether a compiler pass is registered.src/DependencyInjection/*Extension.php and src/DependencyInjection/Configuration.php — the authoritative list of config keys, defaults, and service definitions. Do not trust the README over this file.config/services.yaml (or Resources/config/services.yaml) — the service id and whether it is public or private, plus any autowiring aliases.tests/ — if present, the fastest way to see a working end-to-end invocation.First use case — render a template to a string and return it:
#[Route('/hello/{name}', name: 'hello')]
public function hello(string $name, TemplatorInterface $templator): Response
{
return new Response($templator->render('hello.twig', ['name' => $name]));
}
Confirm the actual service id and interface before writing this:
bin/console debug:container templator
bin/console debug:config templator # use the alias from getAlias()
Inject the interface, not the concrete class. The bundle will expose one primary service (likely templator or templator.renderer). Autowire against its interface so you can decorate or swap it in tests. If the bundle does not register an autowiring alias for the interface, add one in your app's config/services.yaml:
services:
IntellectWebDevelopment\Templator\TemplatorInterface:
alias: templator
Configuration over hardcoding. Anything the extension exposes — template directory, default engine, cache path, delimiters, encoding — belongs in config/packages/templator.yaml, not in constructor calls. Start by copying keys verbatim from Configuration.php; unknown keys fail container compilation, which is actually a useful safety net.
Use it from services and commands, not just controllers. The value of a bundle over a raw library is that the renderer is a container service. Injecting it into a mailer, a Messenger handler, or a console command is the same one-liner as in a controller, and is where most real usage will live (generating emails, invoices, exports):
final class InvoicePdfHandler
{
public function __construct(private TemplatorInterface $templator) {}
public function __invoke(Invoice $invoice): string
{
return $this->templator->render('invoice.html.twig', ['invoice' => $invoice]);
}
}
Wrap rendering in a domain service. Rendering calls scattered across controllers become untestable. Introduce an application-level TemplateRenderer that owns template-name-to-path mapping and a fixed set of view models; the bundle service becomes an implementation detail you can replace.
Tag-based extension if the bundle supports it. If the extension registers a compiler pass, look for tagged renderers/engines/loaders. Adding your own via !tagged_iterator in your services file is the cleanest extension point and avoids fork-the-bundle changes.
Testing. Because the renderer is a service, tests should either (a) let the real bundle render against a tests/templates fixture directory configured per-environment, or (b) bind a stub:
# config/services_test.yaml
services:
IntellectWebDevelopment\Templator\TemplatorInterface:
class: App\Tests\Double\ArrayTemplator
Prefer (a) for at least one smoke test — with a barely-maintained bundle, a single "it renders" test is your regression alarm after every composer update. Run that smoke test on both your current Symfony LTS and, if you are planning to move to 8, on 8 specifically — the 1.1.0 release claims support but has no dependents proving it.
Version pinning. Pin to an exact tag (1.1.0) rather than ^. The 1.1.0 release is a reason to re-read the package, not a reason to trust the range: a version that "supports Symfony 8" frequently gets there by narrowing the supported Symfony range, so an accidental composer update on a Symfony 6/7 app can either refuse to move or, worse, pull in a constraint set nobody has run.
The license is still the single biggest blocker. The 1.1.0 release note says nothing about licensing, and GitHub's detection is unlikely to have changed. Before this goes anywhere near production, read LICENSE/composer.json by hand and confirm the terms are compatible with your distribution model. If there is genuinely no license, you have no grant of rights, regardless of the code being public. Shipping a new minor version without addressing a NOASSERTION result is a signal about maintenance posture generally.
Symfony 8 support means the constraints moved — read them. Check composer.json require for symfony/framework-bundle, symfony/dependency-injection, and php. Two common shapes:
^5.4|^6.0|^7.0|^8.0) — good, nothing to do, but the code path on 8 is untested by anyone but the author.^7.4|^8.0, PHP >=8.4) — this is effectively a breaking change disguised as a minor. Your app on Symfony 6.x will be stuck on 1.0.x forever, and composer update will not tell you why unless you run composer why-not intellect-web-development/templator-symfony-bundle 1.1.0.Symfony 8 itself raises the floor to PHP 8.4 and removes a long list of deprecated APIs (annotations/@Route docblock config, several TreeBuilder/ContainerBuilder helpers, older autowiring conventions). If the 1.1.0 diff is only composer.json, the extension may still call something removed in 8 — the version constraint passing is not proof the bundle works there.
Zero dependents means zero field-testing. Nobody else has run this against a real Symfony app, on any version. Expect rough edges in the DI extension: hardcoded service ids, missing autowiring aliases, public: true on services that should be private, or a Configuration.php with no tree at all (in which case debug:config will error and config keys are read ad hoc from the container parameters). Read the extension file before assuming any config key exists.
Config alias mismatch. The bundle's alias rarely matches the package name. If debug:config templator fails, run bin/console config:dump-reference and look for the bundle's namespace, or read getAlias() directly. Note the alias also governs the YAML filename under config/packages/.
Private service, no alias. A common failure mode in small bundles: the service is defined but neither public nor aliased to its interface, so autowiring fails with "Cannot autowire service ... references interface ... but no such service exists." Fix in your own services.yaml with an explicit alias: — do not edit vendor/.
Clear the cache after every config or template-path change. Template engines wrapped by bundles frequently cache compiled output outside var/cache or keyed by a path that the container doesn't track. When output looks stale, bin/console cache:clear first, then look for a cache_dir-style config key and point it at %kernel.cache_dir%/templator so it is cleared with everything else. This matters double when testing a Symfony upgrade: a stale compiled container can make a broken bundle look fine, or a working one look broken.
Debugging checklist, in order: composer why-not <package> 1.1.0 (constraint sanity), bin/console lint:container (catches wiring errors before runtime), debug:container <service-id> --show-private, debug:autowiring templator, and finally a five-line script that fetches the service from the test container and calls render() directly — that isolates bundle wiring problems from your controller code.
Extension points to check for, in priority order: a tagged-engine/loader compiler pass, a decoratable interface, and config for template resolution paths. If none of those exist, the honest answer is to depend on the underlying templator library directly and drop the bundle — the bundle's only remaining job (service registration) is five lines of YAML you can own yourself, which removes a barely-maintained dependency from your tree without losing functionality. A single "Symfony 8 supported" commit does not change that calculus.
Fork-and-own plan. Given the score, the license ambiguity, and a one-line release note, budget for vendoring: copy the bundle into src/, keep the service definition, drop the composer require. On 1.1.0 that is still usually cheaper than debugging an opaque third-party DI extension on a deadline — and it side-steps the constraint churn entirely, since the five lines of YAML you keep will work on any Symfony version you run.
How can I help you explore Laravel packages today?