如何使会话变量可用作 Twig 全局变量?

How to make session variables available as Twig globals?

在树枝视图中,可以使用

获取会话变量
{% set myVar=app.session.get('myVar') %}

它很方便,但每次我使用不扩展基本模板的视图时都需要这样做。

相反,我想将这些会话变量设置为 twig 全局变量。

我尝试在 config/packages/twig.yaml 中使用 @session,在 globals 下,但在 @session.storage 旁边,我找不到任何方法来访问我的变量。

我想在我的 kernelListener 活动中这样做,但我不知道要导入哪个服务来添加一些动态树枝全局变量(如果可能的话)。

自定义扩展是可行的方法。描述性强,易于测试。不使用 Twig 时无需调用事件监听器。

我的解决方案使用自 Twig 1.35 和 2.4.4

以来可用的 lazy Twig extension

两者都将自动装配和自动配置:

final class SessionRuntime implements RuntimeExtensionInterface
{
    private $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function get(string $id, $default = null)
    {
        return $this->session->get($id, $default);
    }
}

final class SessionExtension extends AbstractExtension
{
    public function getFunctions()
    {
        return [
            new TwigFunction('from_session', [SessionRuntime::class, 'get']),
        ];
    }

    public function getFilters()
    {
        return [
            new TwigFilter('from_session', [SessionRuntime::class, 'get']),
        ];
    }
}

用法:

Hello {{ 'name'|from_session }}. Last visit: {{ 'last_visit'|from_session('never') }}

或者:

Hello {{ from_session('name') }}

如果您真的非常喜欢全局变量,请创建自定义服务并将其绑定到 session 全局变量,例如:

globals:
    session: `@App\Twig\Runtime\SessionRuntime`


class SessionRuntime
{
    private $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function __call(string $key, array $params = [])
    {
        return $this->session->get($key);
    }
}

在 Twig 中:

{{ session.yourSessionKey }}

找到解决方案。
我不得不在我的 kernelListener class

中注入 Twig\Environment
use Twig\Environment as TwigEnvironment;

class kernelListener {
    private $twigEnvironment;

    public function __construct(TwigEnvironment $twigEnvironment,) {
        $this->twigEnvironment=$twigEnvironment;
    }

    public function onKernelController(ControllerEvent $event) {
        $myGlobalValue='someValue';

        /** @var Session $session */
        $session=$event->getRequest()->getSession();
        $session->set('myGlobalValue', $myGlobalValue)


        $this->twigEnvironment->addGlobal('myGlobalValue', $myGlobalValue);
    }
}

有了这个,twigGobalName 可以在所有树枝视图中访问。

有效的 Emix 回答是否正确,因为它也没有错。
只是对我的限制使我自己的答案符合我的需要