noiselabs/smarty-bundle
NoiseLabs SmartyBundle integrates the Smarty template engine into Symfony applications, letting you render .tpl templates alongside Twig, configure Smarty through bundle settings, and use Symfony services and helpers in your views.
The first thing to internalize is that this is a Symfony bundle, not a Laravel package. There is no service provider, no config/smarty.php, and no facade. If you are working in a Laravel codebase you will either (a) use it inside a Symfony service that Laravel consumes as a library, or more realistically (b) pull in smarty/smarty directly and treat this bundle as reference material for how to wire Smarty into a DI container. If you are in a Symfony app, the path is short:
composer require noiselabs/smarty-bundle (pin it — last release is 2021-11-20).NoiseLabs\Bundle\SmartyBundle\SmartyBundle in config/bundles.php (and AppKernel.php on older Symfony).smarty in config/packages/smarty.yaml — at minimum template_dir, compile_dir, cache_dir, and the config_dir..tpl template and return a rendered response.Look first at the bundle's DependencyInjection/Configuration.php (or the README config block) — that is the real API surface. The most valuable first use case is rendering one non-trivial template with a layout/partials and a plugin, because that exercises the asset/helper integration that is the whole reason to use the bundle instead of raw Smarty.
Sanity-check the environment before investing: confirm your PHP version (the 2021 release predates routine PHP 8.2/8.3 work) and your Symfony major version. If either is newer, expect to fork or shim. If you are on Laravel, verify whether you actually need Smarty's syntax (legacy templates, designer collaboration, existing .tpl assets) — if not, Blade or Twig will serve you better.
Treat Smarty as a view engine behind your controllers, not a replacement for the framework's view layer. The clean pattern is: controller builds a plain array of view data, hands it to the Smarty engine service, and returns the rendered string in a Response. Keep presentation logic out of the template and out of the bundle.
Coexistence with Twig/Blade. In a Symfony app you can run Smarty and Twig side by side for a migration window — route legacy .tpl views through $smarty->render() and new views through the native engine. In Laravel, do the equivalent: keep Blade for the app shell, and instantiate Smarty via a small bound singleton for the legacy pages only. Isolate the Smarty boundary in one service so you can delete it later.
View models over raw arrays. Pass small read-only objects or DTOs into Smarty rather than associative arrays stuffed with everything. Smarty resolves properties and methods, and a typed object makes template errors far easier to trace than Array to string conversion from an array key you forgot to set.
Layouts and partials via extends/include. The bundle wires Smarty's template_dir from config, so use {extends file="layout.tpl"} and {include file="partials/_nav.tpl"} rather than concatenating HTML in PHP. Set compile_dir and cache_dir to writable paths outside the docroot (e.g. var/cache/smarty/compile, var/cache/smarty/cache).
Plugins and modifiers for framework helpers. Register custom Smarty plugins (asset URLs, CSRF tokens, route generation, translation) as functions/modifiers so templates stay framework-agnostic and you avoid leaking url() calls into .tpl files. This is the integration tip that pays for the bundle: one registration point, reusable everywhere.
Caching discipline. Use Smarty's per-template caching and cache_lifetime for expensive fragments, but leave it off globally during development. Prefer cache-key variation on the data inputs ($smarty->display('tpl', $cacheId)) rather than long lifetimes.
Testing. Render templates in unit tests by asserting on output strings for critical pages (money, PII, escaped user input), and snapshot the compiled output in CI so a Smarty upgrade cannot silently change rendering.
@smarty Blade directives. Wiring into Laravel means manual singleton binding and replicating the bundle's template_dir configuration yourself.compile_dir is not writable or is cleared by deploy tooling, Smarty may fall back to compile-in-memory (slow) or throw only on the first request. Check the directory permissions in the same place you check storage/ or var/cache/ writability.caching and compile_check are separate switches. Debugging "my template change isn't showing" is almost always compile_check = false or a cached cache_id — not a bundle bug. Disable both in non-production.$smarty->escape_html = true (or the equivalent config key) and prefer explicit |escape on any user-controlled value; an unescaped {$var} is an XSS waiting to happen.php_handling to SMARTY_PHP_REMOVE and enable the security policy if templates come from outside your team. Smarty's {php} tag is a footgun.{ } delimiters collide with inline JavaScript, JSON, and CSS blocks. Configure custom delimiters ({% %}) or wrap JS in {literal} — this is the single most common day-to-day friction.SmartyBC-style custom resources are the escape hatch for framework glue. Register them through the bundle's DI configuration so they are available to every template without per-call setup.How can I help you explore Laravel packages today?