Как создать виджет на Symfony

Часто спрашивают есть ли аналоги виджетов в Symfony, как например в Yii и как их можно реализовать? Для тех кто не знает что такое виджет: виджеты — это многоразовые блоки, обычно используются в видах (вьюхах), чтобы добавить интерфейсу какие-то элементы. C помощью виджетов обеспечивается ООП-подход к повторному использованию кода пользовательского интерфейса.

В качестве примера мы будем создавать виджет, который выводит все категории в сайдбар. Для начала, нам понадобится сам Symfony 4 или 5 версии (чем свежее тем лучше), а так же нам будет нужен шаблонизатор Twig который по умолчанию есть в коробке.

Сразу возникает где мы будем хранить классы виджетов? Все виджеты удобно хранить в папке /src/Widget. Сразу же создаём в этой папке файл CategoriesWidget.php (это название виджета). Так же допустим, что сущность для категорий у вас уже есть.

Пример кода виджета:

<?phpnamespace AppWidget;use SymfonyBundleFrameworkBundleControllerAbstractController; class CategoriesWidget extends AbstractController{    private $em;     public function __construct() 	{        $this->em = $this->getDoctrine()->getManager();    }     public function show() 	{        $categories_rep = $this->em->getRepository(AppEntityCategories::class);        $categories = $categories_rep->findAll();        return $this->render('widgets/category.html.twig',['categories' => $categories]);    }}

как вы видите виджет — это обычный контроллер в Symfony, который ничем не отличается от тех контроллеров которые вы обычно создаете. Однако как нам его использовать в сайдбаре?

Теперь нам нужно создать папку в которой будут лежать шаблоны для наших виджетов.Создаём templates/widgets и там же создаем файл category.html.twig.

Пример файла:

<aside class="widget widget_list_categories">    <h3 class="widget-list-title">        <span>Лучшие рубрики</span>    </h3>    <ul>        {% for cat in categories %}            <li class="item{{ cat.id }}">                <a href="{{ path('category', {slug: cat.slug}) }}">{{ cat.name }}</a> ({{ cat.countPosts }})            </li>        {% endfor %}    </ul></aside>

Теперь нам осталось только вывести нужный виджет в нужном месте. Идём, например, в base.html.twig и создаём там сайдбар, в котором будем рендерить наш виджет категорий.

Пример:

<div id="secondary" class="sidebar widget-area">    {{ render(controller('App\Widget\CategoriesWidget::show')) }}</div>

Вот и все что надо сделать для того что бы начать использовать виджеты в своих проектах. Все оказалось довольно просто!

EnglishRussianUkrainian