Вопрос по rendering, listener, view, symfony – Symfony2: изменить визуализированный вид с помощью слушателя

8

Я хотел бы представить разные взгляды в другом контексте в моем проекте Symfony2. Я использую несколько маршрутов для одних и тех же действий, и я хотел бы отобразить другую страницу (просмотр), но с одним и тем же контроллером. Например у меня есть:

@Route("/articles/show", name="articles_show")
@Route("/mobile/articles/show", name="mobile_articles_show")

Both routes используютthe same action : ArticlesController: showAction (), но должен отображать 2 разных шаблона (для мобильных и обычных пользователей).

show.html.twig
mobile.show.html.twig

Я не хочу использовать оператор if или что-то еще в моем контроллере, поэтому я создал слушатель (аналогично функции preExecute)

Вот часть или мояconfig.yml это определяет мой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 }

Я думал о том, чтобы сделать что-то подобное в слушателеpreExecute function:

if(substr($route,0,7) == 'mobile_'){
    $view = 'mobile.'.$view;
}

К сожалению, я не могу найти способ получить$view или обновите представление «на лету» непосредственно перед его отображением.

Я надеюсь, что мой вопрос достаточно ясен, заранее спасибо, любая идея приветствуется :)

J.

Ваш Ответ

4   ответа
1

@ templating & quot; Служба в качестве аргумента для controller.pre_execute_listener.

Сервис помогает мне рендерить новый, а не получать текущий. Я не могу найти способ получить "текущий" Посмотреть. Jonathan Hell
Ой, извините, я просто предположил, что @templating содержит имя текущего (глупо с моей стороны) :(. В любом случае, я вижу, что вы решили проблему, поэтому вы можете опубликовать ответ самостоятельно и принять его. PS Если вы нужен альтернативный способ переопределения шаблонов смотри мой ответ на эту темуstackoverflow.com/questions/8257676/…
4

что принятое решение на самом деле не работает, если вы возвращаетеResponse-объект (например, когда вы звоните$this->render()), посколькуkernel.view событие не запускается в этом случае:

If the controller doesn't return a Response object, then the kernel dispatches another event - kernel.view.

— see Symfony's HTTP Kernel Docs

Я не мог обойти это, но нашел другое интересное решение для той же проблемы: Вы можете просто расширить движок рендеринга ветки, какZenstruckMobileBundle делает или написать свой собственный локатор файлов, какLiipThemeBundle.

[edit:] В качестве альтернативы вы также можете переопределитьTemplateNameParser.

13

solution:

Сначала я должен послушатьkernel.view, а не kernel.controller.

Затем я использую & quot;@templating& Quot; сервис (спасибо Марко Йованович за подсказку)

Итак, вот мой новый config.yml:

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

Наконец вот мой слушатель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);
    }
}

Надеюсь это поможет!

J.

0

что обнаружение вашего устройства выполнено до того, как вы дойдете до своего маршрута, поэтому держу пари, что вы ожидаете, что мобильный пользователь будет использовать мобильные маршруты благодаря некоторому обнаружению перед запросом, что представляется болезненным для всех шаблонов и генерации URL.

Может быть, лучше обнаружить устройство раньше или позже (благодаряCategorizr или жехорошая конфигурация apache) но не полагаясь на используемый маршрут для мобильного обнаружения.

Интеграция Категоризра ссюда вызова шаблонов рендеринга может быть неплохо.

Затем с помощьюхороший пакет для использования правильных шаблонов / тем или жеиспользуя тот, который обеспечивает более общие функции

Похожие вопросы