symfony/twig-bundle
Symfony TwigBundle integrates the Twig templating engine into the Symfony full-stack framework, providing seamless configuration, services, and rendering support for templates and views within Symfony applications.
While symfony/twig-bundle is Symfony-native, Laravel developers evaluating Twig can mirror its patterns. Start here:
Installation (Symfony Equivalent)
composer require symfony/twig-bundle
For Laravel: Use php-twig + tightenco/jigsaw instead.
First Use Case: Render a Template
Configure config/packages/twig.yaml (Symfony):
twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
Laravel Equivalent:
// routes/web.php
Route::get('/hello', function () {
return response()->view('hello', ['name' => 'Laravel']);
});
Create a Template
templates/hello.html.twig:
<h1>Hello, {{ name }}!</h1>
Key Twig Features to Try Immediately:
{{ variable|upper }}{% for item in items %}{% include 'partials/header.html.twig' %}Access Twig Environment (Symfony)
use Symfony\Bundle\TwigBundle\TwigBundle;
use Twig\Environment;
$twig = $container->get('twig');
$twig->render('hello.html.twig', ['name' => 'Symfony']);
Laravel Equivalent:
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
$loader = new FilesystemLoader('/path/to/templates');
$twig = new Environment($loader);
echo $twig->render('hello.html.twig', ['name' => 'Laravel']);
templates/ (auto-discovered).
templates/
├── base.html.twig # Base layout
├── partials/
│ ├── header.html.twig
│ └── footer.html.twig
└── pages/
└── home.html.twig
resources/views/ (Blade default).jigsaw for asset pipelines.Leverage Symfony’s ecosystem in Twig:
{# Render a Symfony Form #}
{{ form_start(form) }}
{{ form_row(form.name) }}
{{ form_row(form.email) }}
{{ form_end(form) }}
Laravel Equivalent: Use collective/html or Laravel’s native form helpers.
Create reusable logic:
// src/Twig/AppExtension.php (Symfony)
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class AppExtension extends AbstractExtension
{
public function getFunctions(): array
{
return [
new TwigFunction('app_greet', [$this, 'greet']),
];
}
public function greet(string $name): string
{
return "Hello, $name!";
}
}
Usage in Twig:
{{ app_greet('Laravel') }}
Laravel Tip: Register extensions in AppServiceProvider:
$twig->addExtension(new AppExtension());
{# templates/contact.html.twig #}
{{ form_theme(form, 'forms/theme.html.twig') }}
{{ form_widget(form) }}
Laravel Tip: Use laravelcollective/html for similar form rendering.
Symfony’s asset() function handles versioning:
<img src="{{ asset('images/logo.png') }}" alt="Logo">
Laravel Equivalent: Use asset() helper or mix() for Vite.
Symfony’s Web Profiler shows Twig template timings and errors:
{% if app.debug %}
{{ dump(app.request) }}
{% endif %}
Laravel Tip: Use dd() or dump() from laravel-debugbar.
Template Caching
%kernel.cache_dir%/twig.php bin/console cache:clear
php artisan view:clear.Namespace Conflicts
User.html.twig).user_profile.html.twig.Debug Mode
debug: true in twig.yaml for full error details.Template Inheritance
{% extends 'base.html.twig' %}
{% block title %}Homepage{% endblock %}
{% block %} will override content entirely.Auto-Reloading
twig:
auto_reload: false
Avoid Symfony Dependencies
symfony/twig-bundle in Laravel. Use:
composer require twig/twig tightenco/jigsaw
Blade vs. Twig
{{ }} vs. Blade’s {!! !!} for escaping.{% %} vs. Blade’s @.Service Container
AppServiceProvider:
$this->app->singleton(TwigEnvironment::class, function ($app) {
$loader = new FilesystemLoader($app['path.to.views']);
return new Environment($loader, [
'cache' => $app['path.to.cache'],
]);
});
Custom Directives
@directives. Use extensions or PHP callbacks.Performance
php artisan twig:compile
Template Not Found?
paths in twig.yaml (Symfony) or FilesystemLoader (Laravel).Variable Errors
{{ dump(variable) }} to inspect data.{{ app.request.attributes.get('_controller') }} to debug routes.Extension Not Working?
services:
App\Twig\AppExtension:
tags: ['twig.extension']
Circular References
Twig\Error\RuntimeError for circular includes.{% include %} with absolute paths or refactor templates.Custom Filters
// src/Twig/AppExtension.php
public function getFilters(): array
{
return [
new TwigFilter('custom_filter', [$this, 'customFilter']),
];
}
Usage:
{{ 'hello'|custom_filter }}
Global Variables
# config/packages/twig.yaml
twig:
globals:
app_name: 'MyApp'
Access in Twig:
{{ app_name }}
Override Default Settings
twig:
strict_variables: true # Throw errors for undefined vars
autoescape: utf-8 # Force UTF-8 escaping
Integrate with Symfony’s Event System
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
$dispatcher->addListener(KernelEvents::VIEW, function (GetResponseEvent $event) {
$twig = $event->getContainer()->get('twig');
$event->setResponse(new Response($twig->render('custom_response.html.twig')));
});
How can I help you explore Laravel packages today?