如何将全局变量注入到所有模板中?

问题描述 投票:0回答:2

在我的树枝模板中,每个页面都需要一些变量,例如

userName
userId
userImage

将它们注入模板的最佳方法是什么?

我已经阅读了文章如何将变量注入所有模板,但是如何将变量(例如当前用户)写入

config/packages/twig.php
文件中?

现在每个控制器中都有这样的代码:

return $this->render('admin/users/index.html.twig', [
   "allUsers" => $allUsers,
   "pageTitle" => "Benutzerübersicht",
   "userName" => "Max Mustermann",
   "userId" => 5,
   "userImage" => "http://i.pravatar.cc/150?img=6"
]);

(这些只是示例值,因为我尚未集成身份验证,但想创建我的模板)

还有比在每个控制器中注入每个变量更好的方法吗?

php symfony twig symfony4
2个回答
12
投票

您有多种选择,具体取决于您的需求:

您可以使用事件监听器将其作为 Twig 全局变量注入。

  1. 创建监听类:
namespace App\Listener;
// src/EventListener/ControllerListener.php

use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\Security;
use Twig\Environment;

class ControllerListener {
    /**
     * @var \Twig\Environment
     */
    private $twig;
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $manager;
    /**
     * @var \Symfony\Component\Security\Core\Security
     */
    private $security;

    public function __construct( Environment $twig, EntityManager $manager, Security $security ) {
        $this->twig     = $twig;
        $this->manager  = $manager;
        $this->security = $security;
    }

    public function onKernelController( FilterControllerEvent $event ): void {
        $results = $this->manager->getRepository( 'SomeClass' )->findBy( [ 'some' => 'criteria' ] );
        $user    = $this->security->getUser();
        $this->twig->addGlobal( 'veryGlobal', $results[0]->getName() );
        $this->twig->addGlobal( 'username', $user->getUsername() );
    }
}

我正在注射:

  • Twig,这样你就可以在那里添加全局变量。
  • 实体管理器,因此如果您需要从那里获取信息,您可以查询数据库
  • 安全性,从用户那里获取信息。
  1. 创建完成后,您需要添加以下配置行:
# config/services.yaml
services:
    App\EventListener\ControllerListener:
        tags:
            - { name: kernel.event_listener, event: kernel.controller }

这将使事件侦听器能够针对每个请求运行。

使用 twig 配置注入全局服务:

通过这些配置行,如文档中所述,您可以告诉 twig 注入特定服务:

# config/packages/twig.yaml
twig:
    # ...
    globals:
        # the value is the service's id
        users: '@App\Service\UserManagement'

然后就像创建一样简单

App\Service\UserManagement
:

namespace App\Service:

class UserManagement {

   public function __construct() {
      // use the constructor to inject your dependencies, as usual
   }

   public function getOldestUser() {
      // do your thing
      return $oldestUserName;
   }
}

然后从树枝你可以做:

{{ users.oldestUser }}

注意,每次调用

users.OldestUser
时,都会执行该方法,这可能会占用大量资源,具体取决于您正在执行的操作。将结果缓存在该服务的本地属性上可能是一个好主意。

最后,如果您只对登录用户数据感兴趣

正如其他人提到的,如果您只对属于登录用户的数据感兴趣,您可以简单地通过 app 变量访问它,该变量在每个请求上注入

当前用户的表示,如果没有则为 null。存储在该变量中的值可以是 UserInterface 对象、实现 __toString() 方法的任何其他对象,甚至是常规字符串。

例如:

{{ app.user.userName }}
    

2
投票
您正在实现用户界面吗?如果是这样,您可以使用

app.user

,如 
https://symfony.com/doc/current/templatating/app_variable.html 中所述

例如在模板中,您可以使用

{{ app.user.userName }}

 显示当前登录用户的用户名。

© www.soinside.com 2019 - 2024. All rights reserved.