1

Тема: Аналог виджета из yii для symfony

Всем привет. Относительно недавно стал осваивать симфони и сразу стал вопрос - что лучше в использовать когда есть на сайте  елемент, который повторяется практически на всех страницах. Я понимаю что там есть твиг и им можно разбить код как хочешь, но а если у меня не просто статический какой то элемент, а элемент берущий инфу из БД? Непонятно до конца что лучше делать в этом случае... сделать вызов контроллера из вьюхи?

2

Re: Аналог виджета из yii для symfony

mavellol пишет:

сделать вызов контроллера из вьюхи?

Как вариант, один из многих.

Можно накатать расширение для твига, выполняющее ту же функцию, и ставить его одним тегом в любом месте.

Можно накатать сервис и/или хелпер. Зависит от конкретики задачи. Но и вызов контроллера вполне нормальный вариант, не вижу тут особых проблем.

3 Отредактировано Koc (2017-02-27 14:06:27)

Re: Аналог виджета из yii для symfony

Накатал бандл для подобного функционала https://github.com/Koc/BrouzieWidgetsBundle , но все никак не дойдут руки написать документацию.

namespace Metal\TerritorialBundle\Widget;
// php-часть виджета
class CountriesWidget extends TwigWidget implements ContainerAwareInterface
{
    use ContainerAwareTrait;
 
    public function configureOptions(OptionsResolver $resolver)
    {
        // валидация опций, которые может принять виджет
        parent::configureOptions($resolver);
 
        $resolver
            ->setRequired('country')
            ->setAllowedTypes('country', Country::class);
    }
 
    public function getContext()
    {
       // эти данные будут переданы в шаблон виджета, который по-умолчанию находится по адресу @MetalTerritorial/widgets/CountriesWidget.html.twig, но путь к шаблону можно перегрузить через опцию _template
        return array(
            'countries' => $this->container
                ->get('doctrine.orm.default_entity_manager')
                ->getRepository('MetalTerritorialBundle:Country')
                ->getEnabledCountries(),
        );
    }
}

в шаблоне виджета будет доступна переменная countries и _options - это зарезолвленные опции, которые передали в виджет.

а в лейауте дергаем этот виджет как-то так

{{ brouzie_render_widget('MetalTerritorialBundle:Countries', {'country': country}) }}

При желании виджеты можно регистрировать в контейнере, есть опциональное кеширование ответа виджетов, виджеты без шаблонов, отдающие html/json. Можно рендерить виджеты прямо из контроллеров.