【问题标题】:reusable dynamic sidebar in Symfony 4 (Twig)?Symfony 4(Twig)中可重用的动态侧边栏?
【发布时间】:2019-07-31 19:46:10
【问题描述】:

我最近开始使用 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 中发生了变化。

【问题讨论】:

    标签: symfony twig widget symfony4


    【解决方案1】:

    我最终得到了 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 %}
    

    【讨论】:

    • 您可以通过定义以下选项 new TwigFunction('article_sidebar', [$this, 'getArticleSidebar'], [ 'needs_environment' =&gt; true, 'is_safe' =&gt; ['html']]) 并将方法的签名更改为 public function getArticleSidebar(\Twig\Environment $twig) { 来注入 Twig_Environment
    • 您好 DarkBee,感谢您的意见。我更新了答案,因此它使用您的方法注入 Twig_Environment
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 2015-02-07
    • 2022-10-25
    • 2022-01-03
    • 2015-12-01
    • 2017-10-23
    相关资源
    最近更新 更多