twig/extra-bundle
Symfony bundle that auto-enables all Twig “extra” extensions with zero configuration. Install via Composer and instantly access additional Twig features in your Symfony app without manually registering each extension.
Installation:
composer require twig/extra-bundle
(Note: In Laravel, this alone won’t work—requires twig-laravel/twig as a bridge.)
Prerequisite Setup: Install the Laravel Twig bridge:
composer require twig-laravel/twig
Publish the Twig config:
php artisan vendor:publish --provider="Twig\Laravel\TwigServiceProvider" --tag="config"
First Use Case:
Register only non-Symfony extensions in AppServiceProvider:
use Twig\Extra\String\StringExtension;
use Twig\Extra\Text\TextExtension;
public function boot()
{
$twig = app('twig');
$twig->addExtension(new StringExtension());
$twig->addExtension(new TextExtension());
}
Test in a Template:
Create a Twig file (e.g., resources/views/twig/test.twig) and use extensions:
{{ 'hello world'|upper }} {# StringExtension #}
{{ 'Lorem ipsum'|truncate(20, '...') }} {# TextExtension #}
Extension Registration:
$twig->addExtension(new \Twig\Extra\ArrayExtension());
$twig->addExtension(new \Twig\Extra\MarkdownExtension());
FormExtension, UrlExtension) unless mocked.Template Workflows:
{{ 'example.com'|urlencode }} {# StringExtension #}
{{ 'Hello'|lower }} {# StringExtension #}
{{ 'Lorem ipsum'|truncate(10, '...') }} {# TextExtension #}
{{ 'text'|trans }} {# IntlExtension (if mocked) #}
{% for key, value in {'a': 1, 'b': 2}|dictsort %}
{{ key }}: {{ value }}
{% endfor %} {# ArrayExtension #}
Integration with Laravel:
{# Instead of @php Str::title($str) in Blade #}
{{ 'hello world'|title }}
{{ form_start(form) }}
{{ form_widget(form.name) }}
{{ form_end(form) }}
(Requires mocking FormExtension for Laravel.)Dynamic Content:
{% if user.is_admin %}
{{ 'Admin'|trans }}
{% endif %}
{% for item in items|slice(0, 5) %}
{{ item.name }}
{% endfor %}
Hybrid Blade/Twig Projects:
Localization:
trans() with Twig’s IntlExtension:
{{ 'welcome'|trans({'name': user.name}) }}
{{ 'item'|pluralize(count) }} {# IntlExtension #}
Asset Management:
AssetExtension with Laravel’s asset() helper:
{% set css = asset('css/app.css') %}
<link rel="stylesheet" href="{{ css }}">
Avoid Symfony Dependencies:
UrlExtension, CsrfExtension, and FormExtension unless you’re using Symfony components in Laravel.RouterInterface for path()).Leverage Laravel’s Ecosystem:
collective/html for forms instead of FormExtension.AssetExtension with Blade’s @vite() or asset() helper.Testing:
$twig = app('twig');
echo $twig->render('test.twig', ['var' => 'value']);
{{ }} syntax (Twig uses {{ }} and {% %}).Configuration:
config/twig.php) to disable unwanted extensions:
'extensions' => [
Twig\Extra\String\StringExtension::class,
Twig\Extra\Text\TextExtension::class,
// Exclude Symfony extensions
],
Symfony Dependency Conflicts:
http-kernel, form) that may clash with Laravel’s autoloader.--ignore-platform-req=php during installation and test thoroughly.Broken Extensions:
UrlExtension or CsrfExtension won’t work without Symfony’s Router or RequestStack.$router = new class implements \Symfony\Component\Routing\RouterInterface {
public function generate($name, array $parameters = [], $referenceType = self::ABSOLUTE_PATH) {
return route($name, $parameters);
}
};
$twig->addExtension(new \Twig\Extra\UrlExtension($router));
Asset Pipeline Issues:
AssetExtension assumes Symfony’s AssetMapper and won’t work with Laravel’s Vite/Mix.{% set js = asset('js/app.js') %}
<script src="{{ js }}"></script>
CSRF Token Conflicts:
csrf_token may conflict with Blade’s @csrf or Laravel’s csrf_token() helper.@csrf in Blade templates and avoid CsrfExtension in Twig.Form Rendering:
FormExtension, which depends on Symfony’s Form component.collective/html or Livewire for forms in Laravel.Template Caching:
'cache' => storage_path('framework/views/twig'),
Extension Not Loading:
dd($twig->getExtensions());
\Twig\Extra\StringExtension).Runtime Errors:
UrlExtension) will throw:
Cannot instantiate interface Symfony\Component\Routing\RouterInterface
Template Syntax Errors:
{{ }} and {% %}, which may conflict with Blade’s {{ }}..twig extensions for Twig templates and .blade.php for Blade.Missing Functions:
{{ path('route') }} fails, ensure UrlExtension is mocked:
$twig->addExtension(new \Twig\Extra\UrlExtension($router));
Start Small:
String, Text, Array) to avoid complexity.$twig->addExtension(new \Twig\Extra\String\StringExtension());
$twig->addExtension(new \Twig\Extra\Text\TextExtension());
Use Laravel Helpers:
| Twig Extension | Laravel Equivalent |
|---|---|
StringExtension |
Str::* helpers |
AssetExtension |
asset(), @vite() |
UrlExtension |
route(), url() |
Custom Extensions:
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class LaravelExtension extends AbstractExtension
{
public
How can I help you explore Laravel packages today?