Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define global variables for Twig templates with values coming from the DB?

I would like to define a global variable for twig, which would be accessible from any template.

I can create a global variable in symfony's config/packages/twig.yaml, but I need it to be a value obtained from the database.

In the documentation for twig it says to use this code:

$twig = new Twig_Environment($loader);
$twig->addGlobal('name', 'value');

Where should I use this code so this varible is available for every template?

like image 696
Vojtěch Morávek Avatar asked Jan 09 '19 20:01

Vojtěch Morávek


People also ask

How do you set a global variable in Twig?

If you are using Twig in another project, you can set your globals directly in the environment: $twig = new Twig_Environment($loader); $twig->addGlobal('myStuff', $someVariable); And then use {{ myStuff }} anywhere in your application.

How do you access variables in Twig?

In Twig templates variables can be accessed using double curly braces notation {{ variableName }} .

How do you add a global variable?

The global Keyword Normally, when you create a variable inside a function, that variable is local, and can only be used inside that function. To create a global variable inside a function, you can use the global keyword.

What is the name of the object to access global variables from inside a script?

Accessing a Global VariableThe window is the global object in the browser environment. Any property attached to the window object can be accessed from any script on the web page, including the script for the React app. Since window is a global object, the React code can also access its properties, as shown below.


2 Answers

A relatively clean way of doing would be to add an event subscriber that would inject the variables globally before the controllers are instantiated.

The problem of doing in the controller, as one of the comments suggested, is that your globals wouldn't be global at all, but defined only for that controller.

You could do something like this:

// src/Twig/TwigGlobalSubscriber.php

use Doctrine\ORM\EntityManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;

class TwigGlobalSubscriber implements EventSubscriberInterface {

    /**
     * @var \Twig\Environment
     */
    private $twig;
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $manager;

    public function __construct( Environment $twig, EntityManager $manager ) {
        $this->twig    = $twig;
        $this->manager = $manager;
    }

    public function injectGlobalVariables( GetResponseEvent $event ) {
        $whatYouWantAsGlobal = $this->manager->getRepository( 'SomeClass' )->findBy( [ 'some' => 'criteria' ] );
        $this->twig->addGlobal( 'veryGlobal', $whatYouWantAsGlobal[0]->getName() );
    }

    public static function getSubscribedEvents() {
        return [ KernelEvents::CONTROLLER =>  'injectGlobalVariables' ];
    }
}

The DB interaction I left deliberately fuzzy, since only you know exactly what do you want to retrieve from there. But you are injecting the EntityManager on this subscriber, so it's only a matter of retrieving the appropriate repository and perform the appropriate search.

Once this is done, you could simply do from your twig templates something like:

<p>I injected a rad global variable: <b>{{ veryGlobal }}</b></p> 
like image 190
yivi Avatar answered Sep 29 '22 20:09

yivi


Symfony 5.4

service.yml:

   App\Twig\TwigGlobalSubscriber:
        tags:
            - { name: kernel.event_listener, event: kernel.request }

SysParams - my service takes data from the database

src\Twig\TwigGlobalSubscriber.php

<?php

namespace App\Twig;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;

use App\Service\SysParams;

class TwigGlobalSubscriber implements EventSubscriberInterface {

    private $twig;

    public function __construct( Environment $twig, SysParams $sysParams ) {
        $this->twig = $twig;
        $this->sysParams = $sysParams;
    }

    public function injectGlobalVariables() {
        $base_params = $this->sysParams->getBaseForTemplate();
        foreach ($base_params as $key => $value) {
            $this->twig->addGlobal($key, $value);
        }
    }

    public static function getSubscribedEvents() {
        return [ KernelEvents::CONTROLLER =>  'injectGlobalVariables' ];
    }

    public function onKernelRequest()
    {
    }
}
like image 41
GreenCat Avatar answered Sep 29 '22 22:09

GreenCat