簡単!Laravelでtwigテンプレートエンジンを使う実例

さてさて、テンプレート・エンジンといえば有名なSmartyやLaravelに標準搭載されているBladeなどがありますが、ここ最近PHPのテンプレート・エンジンで人気を集めているものがあります。

それが、Twigです。

ウェブサイトを見てもらえばと分かるとおり、こちらもBladeと同じくシンプルかつ高機能を実現しています。

しかし、なぜLaravelを使っているのにTwigを使うかというと、過去に作ったコードを再利用する場合や、そもそもTwigの方に慣れ親しんでいて使いやすいなどの理由を想定しています。

ということで、今回はLaravelTwigテンプレート・エンジンを使う方法です。

ぜひ参考にしてみてくださいね。

※ 実行環境: Laravel 5.7

パッケージをインストール

LaravelTwigを利用する専用パッケージ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.phpLaravel側へコピーします。

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

テンプレートを使うクラス。
初期状態では、TwigBridgeTemplate.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>
        &lt;test&gt;
    </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との不整合が発生する可能性もあるので、それはリスク要因として覚えておく必要はありますね。

ではでは〜!