Symfony2で動的値を自動でテンプレートにアサインする

タイトルの通り、サイトを作っているうえで動的値をテンプレートに自動的にアサインしたい事って結構あるんですよね。
例えば、ログイン機能がついているサイトではログイン中のユーザー情報とか。

Symfony2の場合、Controllerで毎回ログインしているユーザーを取得し、テンプレートに渡すのは非常に面倒です…
軽くググってみたけど、詳細な実装方法が記述されているページがすぐには見つからなかったので書いてみます。

ちなみに静的値をテンプレートに自動的にアサインしたい場合は下記に実装方法が載っています。


動的値の場合には上記ページにも記載されていますが、Twig Extensionを利用して実装します。
ログインしているユーザーをテンプレートに自動的にアサインする例を下記に書いてみます。

1. ログインユーザーを自動的にアサインするTwig Extensionクラスを作成

<?php

namespace Acme\DemoBundle\Twig\Extension;

use Symfony\Component\DependencyInjection\ContainerInterface;

class GlobalAssignExtension extends \Twig_Extension
{
    protected $container;

    /**
     * __construct
     *
     * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * テンプレートにアサインする変数を設定
     *
     * @return array
     */
    public function getGlobals()
    {
        return array(
            'loginUser' => $this->getLoginUser(),
        );
    }

    /**
     * ログイン中のユーザーを取得
     *
     * @return mixed
     */
    protected function getLoginUser()
    {
        $token = $this->container->get('security.context')->getToken();

        if (is_null($token)) {
            return null;
        }

        return $token->getUser();
    }

    /**
     * Returns the name of the extension.
     *
     * @return string
     */
    public function getName()
    {
        return 'global_assign_extension';
    }
}

動的値をテンプレートに自動的にアサインするにはTwigExtensionを継承し、getGlobalsメソッドの返り値として配列を返すとKeyが変数名となりテンプレートで利用することが可能です。
上記のコードではDIコンテナを利用して、ログインしているユーザーを取得してきています。

このクラスを作成した後はサービスとして上記クラスを登録します。

2. 作成したTwig Extensionのサービス登録 (services.yml)

global.assign.twig.extension:
    class: Acme\DemoBundle\Twig\Extension\GlobalAssignExtension
    arguments: [ @service_container ]
    tags:
        - { name: twig.extension }

上記のarguments: [ @service_container ]の行はコンストラクタにコンテナを渡す設定です。
Twig Extensionのサービスを登録するうえで注意が必要なのは、必ずtwig.extensionのタグを指定して下さい。
これがないと自動的に呼ばれることはなく、テンプレートでも変数を利用することは出来ません。

実装は以上でここまで完了すると、どこのテンプレートでもloginUserという変数が利用可能です。