Search code examples
phpsymfonytemplatescontrollers

How to pass a variable to templates for multiple controllers in Symfony 3?


How to specify a group of controllers (e.g. all controllers for an admin section) and assign a variable or a service that would be accessible in all templates rendered by those controllers?

An equivalent in Laravel would be specifying different middleware for different route groups.

I'm NOT looking for these answers:

  1. Global Variables - the variable/service would be unnecessarily injected to some of the controllers (e.g. front-end controllers.)

  2. Embedding other controllers in templates - a workaround that is slow, verbose and repetitive.


Solution

  • To specify controllers that you would like to pass an extra param, let's make its implements some interface like AdminInterface.Then to pass params to view, there are several ways:

    1/listener to kernel.view :

    public function onKernelView(GetResponseForControllerResultEvent $event)
        {
            $result = $event->getControllerResult();
    
            if (!$result instanceof AdminInterface || !isset($result['template']) || !isset($result['data'])) {
                return;
            }
    
            $data = array_merge($result['data'], array('myvar' => 'value'));
            $rendered = $this->templating->render($result['template'], $data);
    
            $event->setResponse(new Response($rendered));
        }
    

    2/pass an attribute a request that contains your params and get it in your controller by $request->attributes->get('myVar') and pass it directly to template.

    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();
        if (!$result instanceof AdminInterface) {
           return;
        }
        $event->getRequest->attributes->set('myvar', 'value');
    }
    

    for more details for symfony kernel events look at doc. Hope help you.