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

时间:2019-05-01 11:34:08

标签: php symfony twig symfony4

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

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

我已经阅读了文章How to Inject Variables into all Templates,但是如何将变量(例如当前用户)写入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"
]);

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

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

2 个答案:

答案 0 :(得分: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() );
    }
}

我正在注射:

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

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

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

使用树枝配置将服务作为全局注入:

使用documentation中所述的以下配置行,您告诉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 }}

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

就像其他人提到的那样,如果您仅对属于登录用户的数据感兴趣,则可以直接访问它through the app variable, which is injected on each request

  

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

例如:

{{ app.user.userName }}

答案 1 :(得分:2)

您是否正在实现UserInterface?如果是这样,您可以按照https://symfony.com/doc/current/templating/app_variable.html

中所述使用app.user

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