Symfony2:使用侦听器更改渲染视图

Jon*_*ell 8 rendering view listener symfony

我想在Symfony2项目中的不同上下文中呈现不同的视图.我正在使用多个路由进行相同的操作,我想渲染一个不同的页面(视图),但使用相同的控制器.例如,我有:

@Route("/articles/show", name="articles_show")
@Route("/mobile/articles/show", name="mobile_articles_show")
Run Code Online (Sandbox Code Playgroud)

两个路由都使用相同的操作:ArticlesController:showAction(),但应该渲染2个不同的模板(对于移动用户和常规用户).

show.html.twig
mobile.show.html.twig
Run Code Online (Sandbox Code Playgroud)

我不想在我的控制器中使用if语句或其他任何东西,所以我创建了一个监听器(类似于preExecute函数)

这是一个定义我的监听器的部分或我的config.yml

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 }
Run Code Online (Sandbox Code Playgroud)

我正在考虑在监听器preExecute函数中做类似的事情:

if(substr($route,0,7) == 'mobile_'){
    $view = 'mobile.'.$view;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我无法找到一种方法来获取$ view或"动态"更新视图,就在渲染之前.

我希望我的问题很清楚,提前谢谢,欢迎任何想法:)

J.

Jon*_*ell 13

这是解决方案:

首先,我必须听kernel.view,而不是kernel.controller.

然后我使用" @templating "服务(感谢Marko Jovanovic提示)

所以这是我的新config.yml:

services:
    controller.pre_execute_listener:
        class: MyProject\MyBundle\Listener\ControllerListener
        arguments: ["@templating"]
        tags:
                - { name: kernel.event_listener, event: kernel.view, method: preExecute }
Run Code Online (Sandbox Code Playgroud)

最后这是我的监听器preExecute函数

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

J.