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

Fel*_*raf 2 php symfony twig symfony4

在我的树枝模板也有一些需要每一页就像变量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"
]);
Run Code Online (Sandbox Code Playgroud)

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

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

yiv*_*ivi 5

您有几种选择,具体取决于您需要什么:

您可以使用事件监听器将其作为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() );
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在注射:

  • Twig,因此您可以在其中添加全局变量。
  • 实体管理器,因此您可以查询数据库是否需要从那里获取信息
  • 安全性,从用户那里获取信息。

    1. 创建之后,您需要添加以下配置行:
# config/services.yaml
services:
    App\EventListener\ControllerListener:
        tags:
            - { name: kernel.event_listener, event: kernel.controller }
Run Code Online (Sandbox Code Playgroud)

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

使用细枝配置来注入全局服务:

使用这些配置行(如本文档所述),您告诉twig注入特定服务:

# config/packages/twig.yaml
twig:
    # ...
    globals:
        # the value is the service's id
        users: '@App\Service\UserManagement'
Run Code Online (Sandbox Code Playgroud)

然后,就像创建一样简单App\Service\UserManagement:

# config/services.yaml
services:
    App\EventListener\ControllerListener:
        tags:
            - { name: kernel.event_listener, event: kernel.controller }
Run Code Online (Sandbox Code Playgroud)

然后,从树枝可以执行以下操作:

{{ users.oldestUser }}
Run Code Online (Sandbox Code Playgroud)

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

就像其他人提到的那样,如果您仅对属于已登录用户的数据感兴趣,则可以通过在每个请求中注入的app变量简单地对其进行访问。

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

例如:

{{ app.user.userName }}
Run Code Online (Sandbox Code Playgroud)