在我的树枝模板中,每个页面都需要一些变量,例如
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"
]);
(这些只是示例值,因为我尚未集成身份验证,但想创建我的模板)
还有比在每个控制器中注入每个变量更好的方法吗?
您有多种选择,具体取决于您的需求:
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() );
}
}
我正在注射:
# config/services.yaml
services:
App\EventListener\ControllerListener:
tags:
- { name: kernel.event_listener, event: kernel.controller }
这将使事件侦听器能够针对每个请求运行。
通过这些配置行,如文档中所述,您可以告诉 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 }}