有没有办法在不在每个操作中传递变量的情况下将内容添加到基本模板?

Is there any way to add Content to the base template without passing the variable in every action?

在 Python 的 Django 中,有一个叫做 context processors 的东西在每个请求之前被调用。这样就可以有,例如,从数据库加载的动态导航。当然,此导航显示在每个页面上,没有人愿意为每个页面手动执行此操作。

在 Symfony 中是否有与这些上下文处理器等效的东西?

我的一个想法是使用 ajax 来提出请求,但这看起来并不十分专业。

在 Symfony 中,我们有正在监听事件的监听器 你可以在这里获得更多信息 https://symfony.com/doc/current/event_dispatcher.html

如果您需要将一些数据从 db 传递到每个 twig 模板,您可以创建 twig 扩展。例如

<?php

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class SomeExtension extends AbstractExtension
{
    private $repository;

    public function __construct(SomeRepository $repository)
    {
        $this->repository = $repository;
    }

    public function getFunctions()
    {
        return [
            new TwigFunction('getWhatEver', [$this, 'getWhatEver']),
        ];
    }

    public function getWhatEver(): array
    {
        return $this->repository->getWhatEver();
    }
}

并在模板调用中 getWhatEver()

因此,您不想将不属于控制器函数的内容传递给控制器​​,而只是将其传递给渲染函数/返回的视图。

例如,Symfony 为 twig 定义了几个默认变量:app 就是其中之一。

它还定义了一个过滤器trans,这显然不是twig的一部分。

看看如何 add/define an extension for twig。为它提供构建导航所需的参数(通过依赖注入),定义并添加 returns 导航数据的树枝函数。确保你的树枝扩展自动加载,然后使用该函数检索导航数据并在模板中构建你的导航,而无需从控制器向模板传递任何内容。 (你可能想将 app.request 传递给你创建的那个 twig 函数,或者可能是一些额外的东西,但这超出了这里的范围)

备选方案:

一个用于 symfony 内核事件的事件侦听器,它将一个全局变量添加到包含数据的树枝(或一个对象来检索它)。

我不认为这是一个干净的解决方案,因为这个侦听器也会 request/create 导航数据,即使调用仅从 json/binary/... 检索数据 api 控制器什么的。 (如果您不在每个请求上构建数据,而是等待模板请求它,则不太明显)