How to add Twig-Globals from custom bundle?

162 Views Asked by At

In a Bundle I try to add a Twig-Global variable to be available in the app where the bundle is used. But it seems I am not allowed or miss something.

Why can't I access the twig parameters and add something? Or how should I do that?

Bundle: ./config/packages/twig.yaml

# config/packages/twig.yaml
twig:
    # this should override the form_themes configuration:
    form_themes: ['@JohnCorpForms/forms/themes/bootstrap_4_layout_custom.html.twig']

    globals:
        # this should add some globals:
        testvar: 'foobar-linus'
        theme_ci: 'blue-grey'
        app_core: '@JohnCorpForms\Utils\Twig\AppTwigGlobals'

Error Message

There is no extension able to load the configuration for "twig" (in "/var/www/myproject/vendor/johncorps/forms-bundle/src/DependencyInjection/../../config/packages/twig.yaml"). Looked for namespace "twig", found "none".

How I load the twig.yaml configuration file:

namespace JohnCorp\FormsBundle\DependencyInjection;

Rent2buyFormsExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../../config'));
        $loader->load(__DIR__ . '/../../config/packages/twig.yaml');
    }
}

Sidnotes

I tried different things to add the twig.yaml to the bundle configuration and have it loaded. According to the error it seems loaded, but to be honest I am a bit confused about how to extend other bundles yaml configuration (like in this case the twig-configuration). Use a compiler pass? Use YamlFileLoader? Use TreeNode? The documentation seems unclear about that or whereever you look you get different approaches (e.g. comparing other bundles approaches). So if anyone knows whats the easiest way to do this, I'd be happy to learn.


Solution / Workaround

Here is my workaround (or maybe it's a proper solution?)

  1. Add a custom TwigExtension, which implements GlobalsInterface src/Utils/Twig/TwigExtension.php
namespace JohnCorp\FormsBundle\Utils\Twig;

use Symfony\Component\HttpFoundation\RequestStack;
use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;

class TwigExtension extends AbstractExtension implements GlobalsInterface
{

    private RequestStack $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    public function getGlobals():array
    {
        return [
            'testvar': 'foobar-linus',
            'theme_ci': 'blue-grey',
            'app_core' => new AppTwigGlobals($this->requestStack),
        ];
    }
}
  1. Load and wire this in Bundle-Class src/JohnCorpFormsBundle.php
class JohnCorpFormsBundle extends AbstractBundle
{
    public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
    {
        parent::loadExtension($config, $container, $builder);

        $definition = $builder
            ->autowire('johncorpforms.twig_extension', TwigExtension::class)
            ->addTag('twig.extension');
    }
}

Now, when using the bundle in a project, I can access app_core.{functionName} everywhere!


PS: Of course I had to wire $requestStack for the AppTwigGlobals::__construct() in services.yaml

services:
    johncorpforms.twig_extension:
        class: JohnCorp\FormsBundle\Utils\Twig\TwigExtension
        arguments:
            $requestStack: '@request_stack'
0

There are 0 best solutions below