symfony2 вызов действия контроллера в расширении прута без обслуживания

Я программирую систему, которая имеет следующие функциональные возможности: обычные пользователи (без программистов и администраторов) могут создавать контент, в который они могут вставлять "заполнители". Эти заполнители будут заменены различными типами контента (например, шестнадцатеричный цветовой код, ползунок, изображение,...) при визуализации страницы. Замена заполнителей немного сложна и имеет некоторые дополнительные функции (например, определение значений по умолчанию, замена заполнителей содержимым на правильном языке,...). Из-за этого я создал расширение ветки с "заполнителем-фильтром". Эта функция должна получить правильный контент для замены заполнителя и обработки дополнительной функциональности. Поскольку типы содержимого настолько различны, есть некоторые - пусть это называется "плагины" - для каждого типа содержимого, который содержит логику для отображения содержимого в контроллере.

Теперь моя проблема:

Контроллер-действия плагинов возвращают визуализированный контент. Поскольку я заменяю заполнитель содержимым в расширении ветки, мне нужен способ вызова действия контроллера в этом расширении ветки.

Мои мысли до сих пор:

Я знаю, что могу вызывать действие контроллера в шаблоне таким образом (источник: http://symfony.com/doc/current/book/templating.html):

{{ render(controller(
        'AppBundle:Article:recentArticles',
        { 'max': 3 }
    )) }}

Так что, кажется, нет проблем с вызовом действия контроллера в ветке. Но мне нужен этот вызов функции в расширении ветки.

Я также знаю, что могу вызвать действие контроллера, когда я реализую контроллер как сервис. Но я не могу определить все контроллеры плагинов как сервисы, потому что плагины включены в систему динамически. Было бы "трудно" обрабатывать сервисы динамически при установке нового плагина (я думаю, что мне нужно отредактировать service.yml с помощью скрипта - или я ошибаюсь?). Вот почему я не могу использовать контроллер в качестве службы. - Но я открыт для других решений, когда вы можете сказать мне, как динамически реализовывать сервисы.

Я уже пробовал объединить решения этих двух страниц: http://symfony.com/doc/current/book/templating.html

echo $view['actions']->render(
    new \Symfony\Component\HttpKernel\Controller\ControllerReference(
        'AppBundle:Article:recentArticles',
        array('max' => 3)
    )
)

и https://www.robinvdvleuten.nl/blog/rendering-templates-in-a-twig-extension/

Теперь у меня есть доступ к Twig_Environment в моем заполнителе-фильтре в моем расширении ветки, но следующий код не работает:

$twig->render( new \Symfony\Component\HttpKernel\Controller\ControllerReference(
                            'Extensions'.$namespace.'Bundle:Index:getContent',
                            array('content'=>$contentObject)
                        ), array() );

Я получаю сообщение об ошибке, что ControllerReference не может быть преобразован в строку (что имеет смысл, потому что ControllerReference является объектом...).

Так есть ли способ вызвать действие контроллера в расширении прута, не определяя контроллер как службу? Или я должен переосмыслить все решение?

2 ответа

Решение

После нескольких часов "размышлений о проблеме" я нашел простой ответ на главный вопрос. Когда я включаю Twig_environment в свою функцию фильтра (см. https://www.robinvdvleuten.nl/blog/rendering-templates-in-a-twig-extension/), я получаю доступ к функции render()- twig. Функция работает с шаблонами и строками. Таким образом, самый простой способ вызвать действие контроллера в расширении ветки без сервисов - это использовать обычный синтаксис twig-template:

// $twig is the Twig_Environment in my filter-function
$myRenderedContent = $twig->render(
    "{{ render(controller( 'Extensions".$namespace."Bundle:Index:getContent', { 'content': content })) }}", 
    array('content'=>$contentObject)
);

Дополнительные мысли:

Как вы можете видеть в http://symfony.com/doc/current/book/templating.html вызов контроллера, подобный этому, кажется вполне приемлемым в Symfony. Так что я думаю, что также можно использовать эту функцию в расширении ветки (поскольку расширение ветки определяет дополнительные вспомогательные функции для рендеринга шаблона, и это то, что я хочу сделать с моей функцией фильтра, чтобы заменить специальные заполнители специальными содержание).

Может быть, это не лучшая практика - не включать мои плагин-контроллеры в качестве сервисов, но я не вижу недостатка в обработке плагин-контроллеров, как это до сих пор - когда вы знаете один: пожалуйста, скажите мне, потому что я открыт научиться "как сделать лучше";-)

Возможно, вы могли бы определить ViewListener и заставить ваш контроллер возвращать нужный вам html вместо ответа, который возвращается $this->render на контроллере.

Вам нужно будет использовать $this->renderView на контроллере и вернуть результат вашему расширению.

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

Другие вопросы по тегам