Reputation: 93
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?
Upvotes: 9
Views: 4837
Reputation: 47370
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>
Upvotes: 13
Reputation: 79
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()
{
}
}
Upvotes: 1