Tech Blog

PHPのテンプレートエンジンTwigを利用する

TwigはPHPのテンプレートエンジンでPythonのDjangoやJinjaと同様の構文を使用します。
ここではTwigを利用して簡単なテンプレートファイルを読み込みPHPの変数を描画します。

1.インストール

まず任意のディレクトリに移動してComposerを使用してTwigのインストールをおこないます。

$ composer require "twig/twig:^3.0"

2.ディレクトリ構成

ディレクトリ構成は以下のようにします。

.
|-- composer.json 
|-- composer.lock 
|-- public        
|   `-- index.php 
|-- templates     
|   |-- base.html 
|   `-- index.html
`-- vendor
    |-- autoload.php
    |-- composer
    |-- symfony
    `-- twig

3.ローカルサーバーの起動

ドキュメントルートになるindex.phpファイルにHelloを出力するようにしておきます。
PHPのビルトインサーバーを起動してブラウザからhttp://localhost:8000/にアクセスします。
正しく動作していればHelloの文字が表示されます。

/public/index.php

<?php
echo 'Hello';
?>

ビルトインサーバーの起動

$ php -S localhost:8000 -t public/

4.テンプレートファイルの作成

/templatesディレクトリ配下にテンプレートファイルを作成していきます。
基となるbase.htmlとbase.htmlを拡張したindex.htmlを作成します。

/templates/base.html

<!DOCTYPE html>
<html>

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

<body>
  <main>{% block content %}{% endblock %}</main>
  <footer>
    {% block footer %}
      © Copyright
    {% endblock %}
  </footer>
</body>

</html>

/templates/index.html

{% extends "base.html" %}

{% block title %}サンプルページ{% endblock %}
{% block head %}
{{ parent() }}
{% endblock %}

{% block content %}
<table>
  <thead>
    <tr>
      <td>氏</td>
      <td>名</td>
      <td>年齢</td>
      <td>日付</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
  </tbody>
</table>
{% endblock %}

5.テンプレートファイルを読み込んで表示する

まずtemplateディレクトリ配下のファイルをpublic/index.phpから読み込んで表示してみます。

/public/index.php

<?php
/*
composerでインストールしたクラスを自動的にロードするためにautoload.phpを読み込みます
*/
require_once __DIR__ . './../vendor/autoload.php';

/*
ディレクトリからテンプレートファイルを検索するローダーを作成する
*/
$loader = new \Twig\Loader\FilesystemLoader(__DIR__. './../templates/');

/*
ローダーをTwig\Environmentに渡してインスタンスを作成する
*/
$twig = new \Twig\Environment($loader, []);


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

ビルトインサーバーを起動した状態でブラウザからhttp://localhost:8000/にアクセスします。
出力されるHTMLは以下のようになります。

<!DOCTYPE html>
<html>

<head>
<title>サンプルページ</title>
  </head>

<body>
  <main><table>
  <thead>
    <tr>
      <td>氏</td>
      <td>名</td>
      <td>年齢</td>
      <td>日付</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
  </tbody>
</table>
</main>
  <footer>
          © Copyright
      </footer>
</body>

</html>

6.変数をテンプレートに流し込んで表示してみます。

index.phpn内で変数$personsを宣言しrenderメソッドの第二引数に渡します。

/public/index.php

<?php

require_once __DIR__ . './../vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader(__DIR__. './../templates/');
$twig = new \Twig\Environment($loader, []);

/*
テンプレートに流し込むデータを作成します。
*/
$persons = array(
    array(
        'firstname' => '太郎',
        'lastname' => '山田',
        'age' => 20,
        'created' => '2021-01-01',
    ),
    array(
        'firstname' => '花子',
        'lastname' => '山田',
        'age' => null,
        'created' => '2021-01-01',
    ),
    array(
        'firstname' => '一郎',
        'lastname' => '田中',
        'age' => 20,
        'created' => '2021-01-01',
    ),
    array(
        'firstname' => '二郎',
        'lastname' => '田中',
        'age' => null,
        'created' => '2021-01-01',
    )
);

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

?>

テンプレートファイル側では変数$personsをループでまわしてそれぞれの要素である連想配列の値を出力して表示します。

/template/index.html


{% extends "base.html" %}

{% block title %}サンプルページ{% endblock %}
{% block head %}
{{ parent() }}
{% endblock %}

{% block content %}
<table>
  <thead>
    <tr>
      <td>氏</td>
      <td>名</td>
      <td>年齢</td>
      <td>日付</td>
    </tr>
  </thead>
  <tbody>
    {% for person in persons %}
      <tr>
        <td>{{ person.lastname }}</td>
        <td>{{ person.firstname }}</td>
        <td>{{ person.age }}</td>
        <td>{{ person.created | date("m/d/y") }}</td>
      </tr>
    {% endfor %}
</table>
{% endblock %}

出力されるHTMLは以下のようになります。

```
<!DOCTYPE html>
<html>

<head>
<title>サンプルページ</title>
  </head>

<body>
  <main><table>
  <thead>
    <tr>
      <td>氏</td>
      <td>名</td>
      <td>年齢</td>
      <td>日付</td>
    </tr>
  </thead>
  <tbody>
          <tr>
        <td>山田</td>
        <td>太郎</td>
        <td>20</td>
        <td>01/01/21</td>
      </tr>
          <tr>
        <td>山田</td>
        <td>花子</td>
        <td></td>
        <td>01/01/21</td>
      </tr>
          <tr>
        <td>田中</td>
        <td>一郎</td>
        <td>20</td>
        <td>01/01/21</td>
      </tr>
          <tr>
        <td>田中</td>
        <td>二郎</td>
        <td></td>
        <td>01/01/21</td>
      </tr>
    </table>
</main>
  <footer>
          © Copyright
      </footer>
</body>

</html>

以上でTwigを利用した表示となります。

公式サイト: https://twig.symfony.com/