九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、テンプレート・エンジンといえば有名なSmartyやLaravelに標準搭載されているBladeなどがありますが、ここ最近PHPのテンプレート・エンジンで人気を集めているものがあります。
それが、Twigです。
ウェブサイトを見てもらえばと分かるとおり、こちらもBladeと同じくシンプルかつ高機能を実現しています。
しかし、なぜLaravelを使っているのにTwig
を使うかというと、過去に作ったコードを再利用する場合や、そもそもTwig
の方に慣れ親しんでいて使いやすいなどの理由を想定しています。
ということで、今回はLaravel
でTwig
テンプレート・エンジンを使う方法です。
ぜひ参考にしてみてくださいね。
※ 実行環境: Laravel 5.7
目次
パッケージをインストール
Laravel
でTwig
を利用する専用パッケージrcrowe/twigbridgeが公開されていますので、これをcomposer
でインストールします。
composer require rcrowe/twigbridge
Laravel 5.5以上を使っている場合はAuto-Discovery
があるので、これでインストールは完了ですが、それ以前のバージョンの場合だとconfig/app.php
でパッケージを登録する必要があります。
'providers' => [ // 省略 TwigBridge\ServiceProvider::class, ],
'aliases' => [ // 省略 'Twig' => TwigBridge\Facade\Twig::class, ],
では、実際にTwig
ファイルを作って実行してみましょう。
Twigを実行してみる
ではtwig
テンプレートをLaravel
で実行する手順をみましょう。アクセスするページはhttp://example.test/home
です。
まず、resources/views/home.twig
を作成して以下の内容で保存します。
<!-- home.twig --> <html> <body> <h1>これは、Twigテンプレートです。</h1> </body> </html>
次にroutes/web.php
を開いてルーティングを設定します。
// web.php Route::get('/home', function(){ return view('home'); // .twigは不要 });
では実際にアクセスしてみましょう。
ここで重要なのが、次のように拡張子以外が同じテンプレートが2つあった場合はtwig
が優先されるということです。
- home.blade.php
- home.twig ・・・ 優先
つまり、もし上記の場合にtwigファイルが削除された場合はhome.blade.php
が自動的に適用されるということになります。
Twigテンプレートに変数を送る
Twig
テンプレートへ変数を送る場合も、Blade
の場合と変わりません。
実際の例を見てみましょう。
文字列の場合
// routes/web.php Route::get('/home', function(){ return view('home', [ 'value' => 'xxx' ]); });
<!-- home.twig --> <html> <body> {{ value }} </body> </html>
実行結果はこうなります。
配列の場合
/*** routes/web.php ***/ Route::get('/home', function(){ return view('home', [ 'values' => ['yyy', 'zzz'] ]); });
<!-- home.twig --> <html> <body> {% for value in values %} {{ value }} {% endfor %} </body> </html>
実行結果はこうなります。
configファイルを使った設定
rcrowe/twigbridge
には、コンフィグ・ファイルを使ってtwig
テンプレートのより細かな設定をする機能があります。
この機能を使うためには、まず以下のphp artisan
コマンドを使ってtwigbridge.php
をLaravel
側へコピーします。
php artisan vendor:publish --provider="TwigBridge\ServiceProvider"
これで、config/twigbridge.php
が作成されましたので、このファイル内で様々な設定をすることができます。
設定内容は次のとおりです。
twig(テンプレートに関する設定)
extension
テンプレートを適用するファイルの拡張子を指定します。例えば、“tpl.php” へ変更した場合、****.tpl.php
がテンプレートとして適用されることになります。
environment
debug
true
にすると、twig内でdump()
が使えるようなります。
{{ dump(values) }}
実行すると次のようになります。
charset
テンプレートで使う文字コードです。
特別な理由がない場合以外は、基本的に “utf-8” がいいでしょう。
base_template_class
テンプレートを使うクラス。
初期状態では、TwigBridge
のTemplate.php
(Twig本体を拡張しているクラス)を使うことになっていますが、独自にTwigを拡張したクラスを使う場合はここで変更することができます。
cache
Twig
のテンプレート・キャッシュは、初期状態ではstorage/views/twig
内に作成されることになっていますが、このフォルダを変更することがでいます。
例えば、storage/twig
フォルダ(書き込み権限を忘れないでください)を作成し、以下のようにするとその中へキャッシュを保存することができます。
'cache' => storage_path('twig'),
auto_reload
キャッシュファイルを常に更新するかどうかを設定する項目です。
つまり、開発中はよく内容を変更するためtrue
にしておき、本番環境はfalse
にすることでパフォーマンスを上げるといいでしょう。
strict_variables
例えば、xxx
という定義されていない変数が使われたときにエラー(例外)を表示するかどうかという設定です。
では実際にやってみましょう。
<!-- home.twig --> <html> <body> <!-- 存在しない変数 "xxx" を使う --> {{ xxx }} </body> </html>
もし初期状態false
の場合、定義されていない変数が使われてもスキップされてエラーは出ませんが、true
の場合は次のようなメッセージが表示されることになります。
autoescape
特殊文字をエスケープする形式(もしくは、しない)を設定する項目です。
例えば、次のようなデータをtwig
へ送信し、
// web.php return view('home', [ 'value' => '<test>' ]);
このように表示するとします。
<!-- home.twig --> <html> <body> {{ value }} </body> </html>
するとHTMLコードは最終的にこのようになって出力されます。
<html> <body> <test> </body> </html>
またこの設定で次のようなエスケープ方法を指定することもできます。
- html ・・・ HTML用エスケープ
- css ・・・ CSS用エスケープ
- js ・・・ JavaScript用エスケープ
- url ・・・ URL用エスケープ
- html_attr ・・・ HTMLのプロパティ用エスケープ
また、独自のエスケープを指定することもできます。
その場合はまず、以下のようにapp/Providers/AppServiceProvider.php
内で次のように独自のエスケープ方法を記述します。
public function boot() { $this->app['twig']->getExtension('core')->setEscaper('replace_dot', function($environment, $string, $charset) { return str_replace('.', '[dot]', $string); }); }
そして、独自エスケープ名を指定してやればいいでしょう。
'autoescape' => 'replace_dot',
これを実行すると “example.com” という文字列は “example[dot]com” となります。
optimizations
テンプレートをコンパイルする際に最適化する方法を指定します。
指定できる方法は以下のとおりです。
- -1 ・・・ 全ての最適化を実行します(OPTIMIZE_ALL)
- 0 ・・・ 最適化をしません(OPTIMIZE_NONE)
- 2 ・・・ 可能な限り
for
を最適化します(OPTIMIZE_FOR) - 4 ・・・ 可能な限り
raw
を最適化します(OPTIMIZE_FOR) - 8 ・・・ 可能な限り変数の作成とアクセスを単純化します(OPTIMIZE_VAR_ACCESS)
globals
どこからでもアクセスできる変数を設定することができます。
例えば、ここへ次のように設定すると、
// twigbridge.php 'globals' => [ 'wherever' => 'どこからでもアクセス可能です!' ],
特に変数を指定しなくても、このようにtwig
テンプレート内からデータを取得することができます。
<!-- home.twig --> <html> <body> {{ wherever }} </body> </html>
extensions
Twig
の拡張を有効にする設定です。
facades
LaravelのFacadeをTwig内で利用できるように設定します。
例えば、Config
を使いたい場合は次のようになります。
// twigbridge.php 'facades' => [ 'Config' ],
<!-- home.twig --> <html> <body> {{ Config.get('app.name') }} </body> </html>
functions
Twig
内で使える関数を設定します。
例えば、初期状態で設定されているlast()
(配列の最後の要素を取得するヘルパー関数)の使い方はこうなります。
<html> <body> {{ last(values) }} </body> </html>
また、直接ここで独自の関数を設定することもできます。
次の例は数字を3桁カンマ区切りにする場合です。
'functions' => [ // 省略 'number_format' => function($number) { return number_format($number); } ],
そして、次のようにすれば数字が3桁カンマ区切りで表示されることになります。
<html> <body> {{ number_format(price) }} </body> </html>
filters
Twigで利用できるフィルターを設定する方法です。
例えば、配列データをJSON化するフィルターを作ってみましょう。
まずフィルターにPHP標準関数のjson_encode()
を設定します。
'filters' => [ // 省略 'json' => 'json_encode' ],
すると、次のようなするだけでjson_encode()
が適用されるようになります。
<html> <body> {{ values | json }} </body> </html>
実際に実行した例です。
["yyy","zzz"]
なお、次のように直接関数を設定することもできます。
'replace_dot' => function($value) { return str_replace('.', '[dot]', $value); }
おわりに
ということで今回はLaravelでTwigテンプレートエンジンを使う方法をご紹介しました。
Twigを使ってみた感想としては、基本的にBladeと同じような構造になっているものの、「フィルター機能」はとても便利だという印象を受けました。
また、変数を表示する部分には$
が必要ないというのも新感覚でした。というのも、$
は左手だけでShiftキーを押しながら4
を押すというちょっとした手間をしないといけないので、この記述法は正直羨ましかったりします(笑)
ただし、LaravelはBladeをテンプレート・エンジンとして開発されたフレームワークなので、もしかするとどこかでTwigとの不整合が発生する可能性もあるので、それはリスク要因として覚えておく必要はありますね。
ではでは〜!