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



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

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

我已经读过《如何将变量注入所有模板》一文,但如何将变量(例如当前用户)写入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"
]);

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

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

您有几个选项,具体取决于您需要什么:

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

  1. 创建一个侦听器类:
namespace AppListener;
// src/EventListener/ControllerListener.php
use DoctrineORMEntityManager;
use SymfonyComponentHttpKernelEventFilterControllerEvent;
use SymfonyComponentSecurityCoreSecurity;
use TwigEnvironment;
class ControllerListener {
/**
* @var TwigEnvironment
*/
private $twig;
/**
* @var DoctrineORMEntityManager
*/
private $manager;
/**
* @var SymfonyComponentSecurityCoreSecurity
*/
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:
AppEventListenerControllerListener:
tags:
- { name: kernel.event_listener, event: kernel.controller }

这将使事件监听器能够在每个请求上运行。

使用分支配置注入服务即全局:

有了这些配置行,如文档中所述,您可以告诉trick注入一个特定的服务:

# config/packages/twig.yaml
twig:
# ...
globals:
# the value is the service's id
users: '@AppServiceUserManagement'

那么它就像创建AppServiceUserManagement:一样简单

namespace AppService:
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时都会执行该方法,这可能会占用大量资源,具体取决于您正在执行的操作。将结果缓存在该服务的本地属性上可能是个好主意。

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

正如其他人所提到的,如果你只对登录用户的数据感兴趣,你可以简单地通过应用程序变量访问它,该变量会在每个请求中注入。

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

例如:

{{ app.user.userName }}

您是否实现了UserInterface?如果是,则可以使用app.user,如中所述https://symfony.com/doc/current/templating/app_variable.html

例如,在您的模板中,您可以使用{{ app.user.userName }}来显示当前登录用户的用户名。

最新更新