многоразовая динамическая боковая панель в Symfony 4 (Twig)? - PullRequest
1 голос
/ 10 марта 2019

Я недавно начал использовать Symfony 4, и сейчас я создаю свой первый веб-сайт с этим замечательным фреймворком.

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

В настоящее время я использую DI во всех этих маршрутах и ​​передаю результат введенного репозитория в шаблон (который включает в себя мой sidebar.html.twig) для маршрута.

public function chalupaBatman(FancyRepository $repository)
{
    $sidebarObjects = $repository->getSidebarObjects();
    $this->render('controllername/chalupabatman.html.twig', [
        'sidebarObjects' => $sidebarObjects,
    ]);
}

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

Пока я нашел эту тему в stackoverflow .

Пользователь Mvin отлично описал мою проблему, а также предоставил некоторые решения.

Однако до сих пор нет ответа на вопрос «что такое лучшая практика», эта тема относится к 2017 году;поэтому способ решения этой проблемы мог измениться в Symfony 4.

1 Ответ

0 голосов
/ 10 марта 2019

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

Хорошо, сначала я создал TwigExtension через командную строку

php bin/console make:twig-extension AppExtension

А затем я изменил класс навыглядят так:

<?php

namespace App\Twig;

use App\Repository\ArticleRepository;
use Psr\Container\ContainerInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AppExtension extends AbstractExtension implements ServiceSubscriberInterface
{
    private $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('article_sidebar', [$this, 'getArticleSidebar'], ['needs_environment' => true, 'is_safe' => ['html']]),
        ];
    }

    public function getArticleSidebar(\Twig_Environment $twig)
    {
        $articleRepository = $this->container->get(ArticleRepository::class);
        $archive = $articleRepository->myAwesomeLogic('omegalul');

        return $twig->render('/article/sidebar.html.twig', [
           'archive' => $archive,
        ]);
    }

    public static function getSubscribedServices()
    {
        return [
            ArticleRepository::class,
        ];
    }
}

Чтобы активировать Lazy Performance, чтобы наш репозиторий и дополнительный Twig_Environment не создавались каждый раз, когда мы используем Twig, мы реализуем ServiceSubscriberInterface и добавляем getSubscribedServices-метод.

Поэтому наши Repo и Twig_Environment создаются только тогда, когда мы на самом деле вызываем {{ article_sidebar() }} внутри шаблона.

{# example-template article_base.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
    <div class="row">
        <div class="col-10">
            {% block article_body %}{% endblock %}
        </div>
        <div class="col-2">
            {{ article_sidebar() }}
        </div>
    </div>
{% endblock %}

Теперь я могу определить свои шаблоны для статьи-маршруты вроде этого:

{# example-template /article/show.html.twig #}
{% extends 'article_base.html.twig' %}
{% block article_body %}
    {# display the article here #}
{% endblock %}
...