Symfony2: Change rendered view with a listener
listener, rendering, symfony, view
Solution
Here is the solution:
First I have to listen to kernel.view, not kernel.controller.
Then I use the "@templating" service (Thanks Marko Jovanovic for the hint)
So here is my new config.yml:
services:
controller.pre_execute_listener:
class: MyProject\MyBundle\Listener\ControllerListener
arguments: ["@templating"]
tags:
- { name: kernel.event_listener, event: kernel.view, method: preExecute }
Finally here is my listener preExecute function
public function preExecute(\Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event){
//result returned by the controller
$data = $event->getControllerResult();
/* @var $request \Symfony\Component\HttpFoundation\Request */
$request = $event->getRequest();
$template = $request->get('_template');
$route = $request->get('_route');
if(substr($route,0,7) == 'mobile_'){
$newTemplate = str_replace('html.twig','mobile.html.twig',$template);
//Overwrite original template with the mobile one
$response = $this->templating->renderResponse($newTemplate, $data);
$event->setResponse($response);
}
}
Hope this helps!
J.
Problem
I would like to render different views in different context in my Symfony2 project. I'm using multiple routes for the same actions and I would like to render a different page (view) but with the same controller. For example I have: ``` @Route("/articles/show", name="articles_show") @Route("/mobile/articles/show", name="mobile_articles_show") ``` Both routes are using the same action : ArticlesController:showAction(), but should render 2 differents templates (for mobile users and regulars ones). ``` show.html.twig mobile.show.html.twig ``` I do not want to use a if statement or whatever in my controller, so I created a listener (similar to a preExecute function) Here is a part or my config.yml that defines my listener ``` services: controller.pre_execute_listener: class: MyProject\MyBundle\Listener\ControllerListener arguments: ["@security.context", "@doctrine", "@router", "@session"] tags:- { name: kernel.event_listener, event: kernel.controller, method: preExecute } ``` I was thinking about doing something like that in the listener preExecute function: ``` if(substr($route,0,7) == 'mobile_'){ $view = 'mobile.'.$view; } ``` Unfortunately I cannot find a way to get $view or update the view "on the fly", just before it's rendered. I hope my question is clear enough, thanks in advance, any idea is welcome :) J.