PHPのテンプレートエンジンTwigを利用してみる

PHPのテンプレートエンジンTwigを利用してみる

TwigはPHPのテンプレートエンジンです。PHPだけでも変数を出力できますが、テンプレートエンジンを使うと簡潔に記述ができるので、コードの可読性が高くなります。

PHPで書いたコードと、PHPのテンプレートエンジンの1つTwigを使ったコードを比べてみましょう。

【PHPで書いたコード】

<?php echo "<p> Hello " . $name . "!</p>"; ?>

【Twigを使ったコード】

<p>Hello {{ name }} !</p>

どちらが見やすいか、一目瞭然ですね!今回は、PHPでTwigを利用する手順を備忘録として残します。

Twigのインストール方法

TwigのコードはGithubにあるので、zipをダウンロードして任意のフォルダに配置してもcloneしても利用できます。

今回はComposerからインストールする手順を残します。ちなみにComposerは既にインストールされているものとします。

Composerのインストールコマンドと生成されるファイル

任意のディレクトリに移動し、次のコマンドでTwigをインストールします。

$ composer require twig/twig:~3.0

「~3.0」は、3.0以上で最新のマイナーバージョンの指定を意味します。詳しくはComposerドキュメントの日本語訳に記載があります。

コマンドを実行すると、実行したフォルダに以下が作成されます。

|-vendor(ディレクトリ)
   |-(依存モジュールのディレクトリ)
   |- :
|-autoload.php
|-composer.json
|-composer.lock

vendorディレクトリ

Twigと依存するモジュール群がインストールされます。

Composerがオートロード情報をautoload.phpに生成します。このファイルをインクロールすればオートロードが行われます。

composer.json

プロジェクトの依存情報が記述されます。上のコマンドを実行した直後のcomposer.jsonは下記の内容でした。

{
   "require": {
      "twig/twig": "~3.0"
   }
}

composer.lock

ロックファイルです。Composerはインストールしたパッケージの実際のバージョンのリストをロックファイルに記録します。

PHPのシステムには、composer.jsonとcomposer.lockとも配置します。Composerの「install」コマンドは、ロックファイルがあればそのバージョンをダウンロードするので、どの環境でも同じバージョンのモジュールをダウンロードできます。

新しいバージョンがあっても自動的にアップデートしないので便利です。新しいバージョンに更新するには「update」コマンドを実行します。

PHPにTwigを組み込んでみる

では、早速TwigをPHPに組み込んでみます。今回は、このような構成で作っていきます。

|-public
   |-index.php
|-template
   |-layout.html
   |-index.html
|-vendor
   |-autoload.php
   |-composer
   |-symfony
   |-twig
|-composer.json 
|-composer.lock

各ファイルに記載する内容は、下記のとおりです。

public/index.php

Twigの組み込みサンプルとして、index.phpを作成します。

<?php
/* Twigをインストールした時に自動生成されたautoload.phpを読み込み
   テンプレートファイルを検索するローダーのインスタンスを作成
*/
require_once __DIR__ . '/../vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader(__DIR__. '/../template/');
$twig = new \Twig\Environment($loader);

/* テンプレートへ引き渡すリストを作成 */
$persons = [
    [
      'name' => '鈴木 一郎',
      'age' => '20',
      'date_register' => '2022-01-01',
   ],
   [ 
     'name' => '鈴木 次郎',
     'age' => '30',
     'date_register' => '2022-02-01',
   ],
   [ 
    'name' => '鈴木 三郎',
    'age' => '40',
    'date_register' => '2022-03-01',
   ],
 ];

/* テンプレートファイルを描画 */
echo $twig->render('index.html', [ 'persons' => $persons ]);

template/layout.html

テンプレートでヘッダーやフッダーなどの要素を繰り返し記述しないよう、レイアウト用のテンプレートを作成します。

Twigはテンプレートの中にテンプレートをネストできます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">

{% block head %}
<title>{% block title %}{% endblock %}</title>
{% endblock %}

</head>
<body>

{% block content %}
{% endblock %}

</body>
</html>

template/index.html

レイアウト用のテンプレートを拡張したindex.htmlテンプレートを作成します。このテンプレートファイルがindex.phpで読み込まれます。

{% extends "layout.html" %}

{% block title %}PHPのテンプレートエンジンTwigを利用してみる{% endblock %}

{% block content %}
<table>
   <thead>
      <tr>
         <th>名前</th>
         <th>年齢</th>
         <th>日付</th>
      </tr>
      </thead>
      <tbody>
      {% for person in persons %}
      <tr>
         <td>{{ person.name }}</td>
         <td>{{ person.age }}</td>
         <td>{{ person.date_register|date("Y/m/d") }}</td>
      </tr>
      {% endfor %}
   </tbody>
</table>
{% endblock %}

出力されるページのHTML

public/index.phpをブラウザーで開くと、次のようなHTMLが出力されます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPのテンプレートエンジンTwigを利用してみる</title>
</head>
<body>
<table>
   <thead>
      <tr>
         <th>名前</th>
         <th>年齢</th>
         <th>日付</th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>鈴木 一郎</td>
         <td>20</td>
         <td>2022/01/01</td>
      </tr>
      <tr>
         <td>鈴木 次郎</td>
         <td>30</td>
         <td>2022/02/01</td>
      </tr>
      <tr>
         <td>鈴木 三郎</td>
         <td>40</td>
         <td>2022/03/01</td>
      </tr>
   </tbody>
</table>
</body>
</html>

Twigでデバックする方法

Twigではdump機能がありますが、Twig_Extension_Debugを追加しないと利用できません。

public/index.phpで次のように、Twig_Extension_Debugを追加すると

//$twig = new \Twig\Environment($loader);
$twig = new \Twig\Environment($loader, ['debug' => true,]);
$twig->addExtension(new \Twig\Extension\DebugExtension());

テンプレートファイルで、dump()が利用できます。

{{ dump(persons) }}