Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Twig Bridge Laravel Package

symfony/twig-bridge

Symfony Twig Bridge integrates Twig with Symfony components, providing templating support across the framework. Includes extensions, form rendering helpers, and tooling to use Twig seamlessly in Symfony applications, with links to docs, issues, and contributions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/twig-bridge
    

    Ensure twig/twig is also installed (required dependency).

  2. Basic Configuration: In config/app.php, register the Twig bridge as a service provider (if not auto-discovered):

    'providers' => [
        // ...
        Symfony\Bridge\Twig\TwigBridgeServiceProvider::class,
    ],
    
  3. First Use Case: Render a Symfony form in a Twig template:

    {{ form_start(form) }}
        {{ form_row(form.field) }}
    {{ form_end(form) }}
    

    Pass the form from your Laravel controller:

    return view('template', ['form' => $form]);
    
  4. Key Files to Explore:

    • config/packages/twig.yaml (Symfony’s default Twig config, adaptable for Laravel).
    • vendor/symfony/twig-bridge/Resources/views/Form/ (default form themes).
    • app/Views/ (your custom Twig templates).

Implementation Patterns

1. Form Integration

  • Dynamic Form Themes: Override Symfony’s default form themes by creating a form_theme.html.twig in your resources/views/:

    {# app/Resources/views/form_theme.html.twig #}
    {% block form_row %}
        <div class="form-group">
            {{ form_label(form) }}
            {{ form_errors(form) }}
            {{ form_widget(form) }}
        </div>
    {% endblock %}
    

    Register it in your controller:

    $form->setTheme([new \Twig\Template\TemplateName('form_theme.html.twig')]);
    
  • Validation-Focused Workflow: Leverage Symfony’s validation helpers in Twig:

    <input type="text"
           {{ form_widget(form.field, { 'attr': {'aria-invalid': form.field.vars.errors|length > 0} }) }}>
    

2. Security Integration

  • Role-Based Access Control (RBAC): Use Symfony’s access_decider in Twig:
    {% if app.security.authorization_checker.access_decision('ROLE_ADMIN') == 'granted' %}
        <a href="/admin">Admin Panel</a>
    {% endif %}
    
    Or with the Twig extension:
    {% if app.security.access_decision('ROLE_USER') == 'granted' %}
        {# User-specific content #}
    {% endif %}
    

3. Translation and Internationalization

  • Symfony’s Translator: Access translations directly in Twig:
    {{ 'welcome.message'|trans({'%name%': user.name}) }}
    
    Configure the translator in config/services.php:
    'translator' => [
        'default_locale' => 'en',
        'fallback_locale' => 'en',
        'paths' => [__DIR__.'/../resources/translations'],
    ],
    

4. Service Injection

  • Pass Symfony Services to Twig: Bind services in config/services.php:
    'twig' => [
        'globals' => [
            'app' => App::class, // Your custom service
        ],
    ],
    
    Use in Twig:
    {{ app.someMethod() }}
    

5. Email Templates

  • Templated Emails: Use Symfony’s TemplatedEmail with Twig:
    use Symfony\Bridge\Twig\Mime\TemplatedEmail;
    
    $email = (new TemplatedEmail())
        ->from('sender@example.com')
        ->to('user@example.com')
        ->subject('Welcome!')
        ->htmlTemplate('emails/welcome.html.twig')
        ->context(['name' => 'John']);
    

6. Custom Twig Extensions

  • Extend Twig with Symfony Logic: Create a custom extension:
    namespace App\Twig;
    
    use Twig\Extension\AbstractExtension;
    use Twig\TwigFunction;
    
    class AppExtension extends AbstractExtension
    {
        public function getFunctions(): array
        {
            return [
                new TwigFunction('app_function', [$this, 'doSomething']),
            ];
        }
    
        public function doSomething(): string
        {
            return 'Custom logic here';
        }
    }
    
    Register it in config/services.php:
    'twig' => [
        'extensions' => [App\Twig\AppExtension::class],
    ],
    
    Use in Twig:
    {{ app_function() }}
    

Gotchas and Tips

Pitfalls

  1. Caching Conflicts:

    • Issue: Twig’s cache may conflict with Laravel’s cache system, causing stale templates.
    • Fix: Configure Twig’s cache directory explicitly in config/packages/twig.yaml:
      twig:
          cache: '%kernel.cache_dir%/twig'
      
  2. Form Theme Overrides:

    • Issue: Custom form themes may break if Symfony’s default themes are not properly extended.
    • Fix: Always extend the parent block:
      {% extends 'form_div_layout.html.twig' %}
      
  3. Symfony-Specific Assumptions:

    • Issue: Some TwigBridge features assume Symfony’s Container or Kernel (e.g., app.security).
    • Fix: Mock or alias Symfony services in Laravel’s container:
      $this->app->bind('security.authorization_checker', function ($app) {
          return new LaravelAuthorizationChecker(); // Custom implementation
      });
      
  4. Deprecated Methods:

    • Issue: Older versions of phpdocumentor/reflection-docblock may cause conflicts (e.g., v6+).
    • Fix: Update dependencies or pin versions in composer.json:
      "require": {
          "phpdocumentor/reflection-docblock": "^5.3"
      }
      
  5. Block Prefix Leaks:

    • Issue: Nested Twig collections may leak block prefixes (e.g., block_name_0, block_name_1).
    • Fix: Use unique block names or update to Symfony 6.4.32+.
  6. Bootstrap 4 Form Layouts:

    • Issue: Form errors may render incorrectly in Bootstrap 4 layouts.
    • Fix: Update to Symfony 7.4.7+ or manually adjust form themes.

Debugging Tips

  1. Enable Twig Debugging: Set debug: true in config/packages/twig.yaml:

    twig:
        debug: '%kernel.debug%'
        strict_variables: '%kernel.debug%'
    
  2. Check Template Inheritance: Use {{ dump(_context) }} to inspect the template context and inheritance chain.

  3. Symfony Profiler Integration: Install symfony/web-profiler-bundle for Twig template profiling:

    composer require symfony/web-profiler-bundle
    
  4. Form Debugging: Enable form debugging in Twig:

    {{ form(form, { 'attr': {'data-form-debug': true} }) }}
    

Extension Points

  1. Custom Form Types: Extend Symfony’s form types for Laravel:

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    
    class LaravelFormType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('field', TextType::class);
        }
    }
    

    Register it in config/services.php:

    'form.types' => [
        'laravel_form' => App\Form\LaravelFormType::class,
    ],
    
  2. Twig Runtime Integration: Override Symfony’s TwigRuntime for custom logic:

    namespace App\Bridge\Twig;
    
    use Symfony\Bridge\Twig\Extension\TwigExtension;
    use Symfony\Bridge\Twig\TwigRuntime;
    
    class CustomTwigRuntime extends TwigRuntime
    {
        public function customMethod()
        {
            return 'Custom runtime logic';
        }
    }
    

    Bind it in config/services.php:

    'twig.runtime' => App\Bridge\Twig\CustomTwigRuntime::class,
    
  3. Event Listeners: Listen to Twig events (e.g., Twig\EventDispatcher\TemplateEvents::PRE_RENDER):

    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Twig\EventDispatcher\TemplateEvents;
    
    class TwigEventSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                TemplateEvents::PRE_RENDER => 'onPreRender',
            ];
        }
    
        public function onPreRender
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport