I see several ways to handle this.
Adding a global variable from kernel.request
The idea is to add a global variable right after the kernel.request event.
services.yml
services: class: Acme\FooBundle\Listener\MyListener arguments: - @twig tags: - name: kernel.event_listener event: kernel.request method: onKernelRequest
Mylistener
class MyListener { protected $twig; public function __construct(\Twig_Environment $twig) { $this->twig = $twig; } public function onKernelRequest(GetResponseEvent $event) { $myVar = 'foo';
Now you can use it anytime by doing
{{ myvar }}
From the kernel.view
First, you need to understand when kernel.view is kernel.view . It is called only when the controller return is not an instance of the Response object .
However, doing
// Acme/FooBundle/FooController
returns a response object , so kernel.view not called.
Controller Definition
The idea is to force the entire controller to return an array of data, just like @Template requirements.
// Acme/FooBundle/FooController
Service definition
Since you already have a service definition, you just need to add some requirements to the service declaration.
To render data, you need the @templating service.
You must set yourself as a kernel.view listener
// Acme/FooBundle/Resources/config/services.yml services: acme_foo.my_listener: class: Acme\FooBundle\Listener\MyListener arguments: - @templating tags: - name: kernel.event_listener event: kernel.request method: onKernelRequest - name: kernel.event_listener event: kernel.view method: onKernelView
Service Creation
// Acme/FooBundle/Listener/MyListener.php use Symfony\Component\Templating\EngineInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; class MyListener { protected $templating; protected $myVar; public function __construct(EngineInterface $templating) { $this->templating = $templating; } public function getMyVar() { return $this->myVar; } public function onKernelRequest(GetResponseEvent $event) { $this->myVar = ""; // Process MyVar data } public function onKernelView(GetResponseForControllerResultEvent $event) { $result = $event->getControllerResult(); if (null === $this->myVar || !isset($result['template']) || !isset($result['data'])) { return; } $data = array_merge($result['data'], array('myvar' => $this->myVar)); $rendered = $this->templating->render($result['template'], $data); $event->setResponse(new Response($rendered)); } }
And here you are. The listener creates a new response by adding his custom myvar definition to any template he provides.
From the TWIG extension
An alternative is to create a TWIG extension . In the following example, I assume that the definition of MyListener is the same as above.
Service Definition
According to the documentation above, you just need to create a simple extension class.
// Acme/FooBundle/Resources/config/services.yml services: acme_foo.my_listener: class: Acme\FooBundle\Listener\MyListener tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } acme_foo.my_extension: class: Acme\FooBundle\Extension\MyExtension arguments: - @acme_foo.my_listener tags: - { name: twig.extension }
Service definition
As in the documentation, we will create a simple function.
// Acme/FooBundle/Extension/MyExtension.php use Acme\FooBundle\Listener\MyListener; class MyExtension extends \Twig_Extension { protected $listener; public function __construct(MyListener $listener) { $this->listener = $listener; } public function getName() { return 'my_extension'; } public function getFunctions() { return array( 'myvar' => new \Twig_Function_Method($this, 'getMyVar') ); } public function getMyVar() { return $this->listener->getMyVar(); } }
Using
Then you can use it in any view by doing
{{ myvar() }}
From a shared controller
I do not like this idea, but it is an alternative. You just need to create a BaseController that will override the default render method.
// Acme/FooBundle/Controller/BaseController.php abstract class BaseController extends Controller { public function render($view, array $parameters = array(), Response $response = null) { $parameters = array_merge( $parameters, array( 'myvar' => $this->get('my_listener')->getMyVar() ) ); return parent::render($view, $parameters, $response); } }