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