【FuelPHP】PresenterのViewをTwigにする

投稿日:

ポケモンGo全然興味なかったのにあれやばいっすわー。

というわけで、FuelPHPにおいてPresenterのViewをTwigにしました。
その経緯をメモしておきます。

前提条件

  • FuelPHPのバージョンは1.7.2でインストール済みである
  • composerの導入も済んでいる
    • Twigのインストールはcomposerを使います

手順

では手順を書いていきます。

composer.jsonの修正

こんな感じで、composer.jsonに"twig/twig" : "1.*"を追記します。

  • 現時点(2016/07/26)では1.24.2-DEVが入ります
  • devが気になる場合、"twig/twig" : "1.24.1"などとバージョン指定をして書けばいいです
  • インストール後、echo Twig_Environment::VERSION;でバージョンの確認ができます
"require": {
    ・
    ・
    ・
    "michelf/php-markdown": "1.4.0",
    "twig/twig" : "1.*" // これを追加
},

composerのアップデート

そうしたらcomposerのアップデートです。

$php composer.phar update

fuel/app/config/config.php の修正

Twigを使えるようにParser packageを有効化します。

/**************************************************************************/
/* Always Load                                                            */
/**************************************************************************/
'always_load'  => array(

    /**
     * These packages are loaded on Fuel's startup.
     * You can specify them in the following manner:
     *
     * array('auth'); // This will assume the packages are in PKGPATH
     *
     * // Use this format to specify the path to the package explicitly
     * array(
     *     array('auth'	=> PKGPATH.'auth/')
     * );
     */
    'packages'  => array(
    	'parser', // これを追加
    ),
)

fuel/app/config/routes.php にルートの追加

サンプルの確認用にルーティングを設定します。

例) こんなURLでアクセスできるようにする
http://localhost:8000/twig/sample

// twig sample
'twig/sample' => 'twig/sample/index'

コントローラー

fuel/app/classes/controller/twig/sample.php を作成し以下の様に書きます。

<?php
/**
 * Twig Sample Controller
 */
class Controller_Twig_Sample extends Controller
{
    /**
     * @return \Response
     */
    public function action_index()
    {
        // viewファイルの指定(views/twig/sample.twig)
        // プレゼンターの指定でもある(presenter/twig/sample.php)
        // 上記はセットで必要
        $view = 'twig/sample';

        // TwigのViewを生成
        $twig = \View_Twig::forge($view);

        // Presenterの第4引数にTwigのViewを渡す
        $presenter = \Presenter::Forge($view, 'view', null, $twig);

        return \Response::forge($presenter);
    }
}

ポイント

Presenterに何かしらのプロパティをここでセットしたい場合、

$presenter = \Presenter::Forge($view, 'view', null, $twig);
$presenter->set('hoge', 'piyo');

// あえてエスケープさせない場合はこうする
// $presenter->set('hoge', 'piyo', false);

return \Response::forge($presenter);

の様にすると、後述するプレゼンタークラスの中で

echo $this->hoge; // => piyo

と使えます。
※ viewにもセットされます

プレゼンター

fuel/app/classes/presenter/twig/sample.php を作成し以下の様に書きます。

<?php
/**
 * Twig Sample Presenter
 */
class Presenter_Twig_Sample extends Presenter
{
    /**
     * レンダリング
     */
    public function view()
    {
        $title = 'Twig Test';
        $this->title = $title;
        $this->h1 = $title;

        // デフォルトはエスケープされる(Presenter側で)
        // __set()が呼ばれて、その中でset()が呼ばれている(set()はデフォルトでエスケープする)
        $this->helloworld = '<strong>Hello World!!</strong>';

        // 上記にある通りエスケープされる
        $this->set('helloworld2', '<strong>Hello World!! 2</strong>');

        // これはエスケープされない
        // あえてHTMLとして認識させたい場合とか
        // template側でエスケープ出来る
        $this->set('hellotwig', '<strong>Hello Twig!!</strong>', false);
    }
}

ビュー

ビューの作成ですが、せっかくなのでTwigっぽくレイアウト用のviewファイルも作成します

  • fuel/app/views/twig/layout.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
{% block content %}{% endblock %}
</html>

コンテンツ部分はこんな感じです。

  • fuel/app/views/twig/layout.twig
{% extends "layout.twig" %}
{% block content %}
<body>
  <h1>{{ h1 }}</h1>

  <h3>デフォルトはエスケープされる(presenter側で)</h3>
  <p>{{ helloworld }}</p>
  <p>{{ helloworld2 }}</p>

  <h3>あえてエスケープさせない</h3>
  <p>{{ hellotwig }}</p>

  <h3>{{'{{'}} value|e {{'}}'}} でエスケープさせる</h3>
  <p>{{ hellotwig|e }}</p>
</body>
{% endblock %}

ポイント

extends "layout.twig" と書くと、相対パスでテンプレートを見てくれます。
逆に任意のテンプレートを見たい場合は、extends "parts/layout.twig" の様に書くと、fuel/app/views/parts/layout.twigからテンプレートを見てくれます。
viewファイル置き場 (ここではfuel/app/views/~) から探してくれる様ですね。

見てみる

http://localhost:8000/twig/sample にアクセスして、こんな画面になっていたら成功です。

Twig Test

その他

{{ }} をテンプレートで使いたい

デフォルトでtwigは {{ }} の文字でパースします。
じゃあ {{ }} を使いたい場合どうするの?って所ですが(そんな場面があるのか不明ですが)、

{{ '{{' }}{{ h1|e }}{{ '}}' }} {# {{Twig Test}} と表示される #}

こうすればよいみたいです。
{{ '{{' }}の様に書く。
上記の例にも書いています({{‘{{‘}} value|e {{‘}}’}} でエスケープさせる)。

var_dump() 的なものを有効化

テンプレート側でセットされた値をデバッグしたいことが絶対あると思います。
Twigにはdump()というテンプレート側でvar_dump()的な事をしてくれるヘルパーメソッドがあるので、これを使えるようにします。
※ 使えるようにするのがちょうめんどくさいです。なんでデフォルトですぐ使えないの?

fuel/packages/parser/config/perser.php の修正

// TWIG ( http://www.twig-project.org/documentation )
// ------------------------------------------------------------------------
'View_Twig' => array(
	'auto_encode' => true,
	'views_paths' => array(APPPATH.'views'),
	'delimiters' => array(
		'tag_block'     => array('left' => '{%', 'right' => '%}'),
		'tag_comment'   => array('left' => '{#', 'right' => '#}'),
		'tag_variable'  => array('left' => '{{', 'right' => '}}'),
	),
	'environment' => array(
		'debug'                => true, // trueにする
		'charset'              => 'utf-8',
		'base_template_class'  => 'Twig_Template',
		'cache'                => APPPATH.'cache'.DS.'twig'.DS,
		'auto_reload'          => true,
		'strict_variables'     => false,
		'autoescape'           => false,
		'optimizations'        => -1,
	),
	'extensions' => array(
		'Twig_Fuel_Extension',
		'Twig_Extension_Debug' // こいつを追加
	),
),
  • View_Twig.environment.debugtrueにする
  • View_Twig.extensions'Twig_Extension_Debug'を追加

上記を施すと、テンプレート内で
{{ dump($val) }}
の様に書けてダンプ出来ます。

確認

テンプレートにこう書いてみます。

{% extends "layout.twig" %}
{% block content %}
<body>

  {{ dump(hellotwig) }} {# '<strong>Hello Twig!!</strong>' と表示される #}

</body>
{% endblock %}

環境ごとに設定を分ける

例えば、実行環境がローカル開発環境developmentだった場合、
fuel/app/config/development/parser.phpのファイルを作成して以下の様にしておくとローカル開発環境のみ適用されます。

<?php
/**
 * Fuel
 *
 * Fuel is a fast, lightweight, community driven PHP5 framework.
 *
 * @package    Fuel
 * @version    1.7
 * @author     Fuel Development Team
 * @license    MIT License
 * @copyright  2010 - 2014 Fuel Development Team
 * @link       http://fuelphp.com

/**
 * NOTICE:
 *
 * If you need to make modifications to the default configuration, copy
 * this file to your app/config folder, and make them in there.
 *
 * This will allow you to upgrade fuel without losing your custom config.
 */

return array(
    // TWIG ( http://www.twig-project.org/documentation )
    // ------------------------------------------------------------------------
    'View_Twig' => array(
        'auto_encode' => true,
        'views_paths' => array(APPPATH.'views'),
        'delimiters' => array(
            'tag_block'     => array('left' => '{%', 'right' => '%}'),
            'tag_comment'   => array('left' => '{#', 'right' => '#}'),
            'tag_variable'  => array('left' => '{{', 'right' => '}}'),
        ),
        'environment' => array(
            'debug'                => true, // trueにする
            'charset'              => 'utf-8',
            'base_template_class'  => 'Twig_Template',
            'cache'                => APPPATH.'cache'.DS.'twig'.DS,
            'auto_reload'          => true,
            'strict_variables'     => false,
            'autoescape'           => false,
            'optimizations'        => -1,
        ),
        'extensions' => array(
            'Twig_Fuel_Extension',
            'Twig_Extension_Debug' // こいつを追加
        ),
    ),
);

環境の設定が済んだらfuel/packages/parser/config/parser.phpに記載した設定は元に戻しておきます。

気になった事

View_Twig.environment.debugtrueにするとテンプレートに変更があった際、コンパイルされて必ず変更されるけど、View_Twig.environment.debugfalseにするとキャッシュを見るから変更があったらキャッシュは消さなきゃいけないよ。
みたいな記事をよく見かけたんですが、手元でやってみた限りView_Twig.environment.debugfalseのままでも変更内容は反映されました。

自分が思うに、View_Twig.environment.auto_reloadtrueであれば変更したものは反映される気がしています。
View_Twig.environment.auto_reloadfalseにすると、変更内容は無視されました(キャッシュの値が返される ※動的部分は反映されます)。
その後キャッシュファイルを消したら変更内容が反映されました(新しいキャッシュファイルも作成された)。

該当ソース/fuel/vendor/twig/twig/lib/Twig/Environment.phpにもこうあります。

auto_reload: Whether to reload the template if the original source changed
オリジナルのソースが変更された場合、テンプレートをリロードするかどうか。

なので、auto_reloadがtrueであれば変更は反映されるはずです!
違っていたら突っ込んでください!
(もっとソースを追えって話ですが。。)

まとめ

結構簡単にTwigを使うことが出来ました!
淡々と書いていて何事も無く出来たと思いましたか?
ちょっとした落とし穴があったので次の記事で書きますよ!

2016/07/27 追記

次の記事書きました!!

参考にさせて頂きました

作成者: shimabox

Web系のプログラマをやっています。 なるべく楽しく生きていきたい。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください