我最近开始使用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中更改。
答案 0 :(得分:0)
我最终得到了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,
];
}
}
为了激活惰性性能,因此当我们使用Twig时,不会每次都实例化我们的存储库和其他Twig_Environment
我们实现ServiceSubscriberInterface
并添加getSubscribedServices
方法。
因此,仅当我们在模板中实际调用{{ article_sidebar() }}
时,实例化我们的Repo和Twig_Environment。
{# 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 %}