SlimPHPのテンプレートエンジンとして、Twigを利用する手順をまとめておきます。
掲載したコードは Templates - Slim Framework のものを、SlimPHPのSkeletonプロジェクトで動くように書き換えたものです。
SlimPHPプロジェクトの作成
- composerはグローバルで動くものとする
- ターミナルを起動
- プロジェクトフォルダーを作りたいフォルダーに移動
- 以下でプロジェクトを作成(slim-twig-test フォルダーをプロジェクトフォルダーにする場合の例)
composer create-project slim/slim-skeleton slim-twig-test cd slim-twig-test composer require slim/twig-view
- 作成したフォルダー内に出来上がる composer.json をテキストエディタで開く
- "require" 欄から "slim/php-view" の行は不要なので削除して、上書き保存
- ターミナルで以下を実行して、インストール環境を更新する
composer update
設定ファイルを準備する
テンプレート用のパスと、Twigのオプションを設定します。PHPの組み込みサーバーで動作しているかどうかで、デバッグと本番設定を切り替えられるようにします。本番用は cache を利用し、デバッグ用は debug フラグをtrueにして、更新を監視するようにします。
- /src/settings.php を開く
- 以下のように修正
<?php return [ 'settings' => [ 'displayErrorDetails' => true, // set to false in production // Twig settings 'view' => [ 'template_path' => __DIR__ . '/../templates/', 'options' => [ 'cache' => __DIR__ . '/../cache/' ] ], // Monolog settings 'logger' => [ 'name' => 'slim-app', 'path' => __DIR__ . '/../logs/app.log', ], ], ];
<?php return [ 'settings' => [ 'displayErrorDetails' => true, // set to false in production // Twig settings 'view' => [ 'template_path' => __DIR__ . '/../templates/', 'options' => [ 'debug' => true ] ], // Monolog settings 'logger' => [ 'name' => 'slim-app', 'path' => __DIR__ . '/../logs/app.log', ], ], ];
- 設定を読み込むために /public/index.php を開いて以下の通りにする
<?php if (PHP_SAPI == 'cli-server') { // To help the built-in PHP dev server, check if the request was actually for // something which should probably be served as a static file $file = __DIR__ . $_SERVER['REQUEST_URI']; if (is_file($file)) { return false; } $settings = require __DIR__ . '/../src/settings-debug.php'; } else { $settings = require __DIR__ . '/../src/settings.php'; } require __DIR__ . '/../vendor/autoload.php'; session_start(); // Instantiate the app $app = new \Slim\App($settings); // Set up dependencies require __DIR__ . '/../src/dependencies.php'; // Register middleware require __DIR__ . '/../src/middleware.php'; // Register routes require __DIR__ . '/../src/routes.php'; // Run app $app->run();
コンテナにTwigを設定
SlimPHPのコンテナにTwigを追加します。
- /src/dependencies.php を開く
- 以下のようにする
<?php // DIC configuration $container = $app->getContainer(); // view renderer $container['view'] = function ($c) { $settings = $c->get('settings')['view']; $view = new \Slim\Views\Twig( $settings['template_path'], $settings['options'] ); $view->addExtension(new \Slim\Views\TwigExtension( $c['router'], $c['request']->getUri() )); return $view; }; // monolog $container['logger'] = function ($c) { $settings = $c->get('settings')['logger']; $logger = new Monolog\Logger($settings['name']); $logger->pushProcessor(new Monolog\Processor\UidProcessor()); $logger->pushHandler(new Monolog\Handler\StreamHandler($settings['path'], Monolog\Logger::DEBUG)); return $logger; };
ルートを設定
リクエストに応じた処理を呼び出すルートを設定します。今回は、 http://0.0.0.0:8080/hello を呼び出すと、与えられた配列のユーザー一覧を表示して、 http://0.0.0.0:8080/hello/ユーザー名 とすると、指定したユーザーのプロフィールを表示するようにします。
- /src/routes.php を開いて、以下のようにする
<?php // Routes // ユーザー一覧 $app->get('/hello', function($request, $response, $args) { // ユーザー一覧 $users = [ 'Tama', 'Kotta', 'Tanaka' ]; return $this->view->render($response, 'list.html', [ 'list' => $users ]); })->setName('list'); // 指定のユーザーのプロフィールを表示 $app->get('/hello/{name}', function ($request, $response, $args) { return $this->view->render($response, 'profile.html', [ 'name' => $args['name'] ]); })->setName('profile');
/hello で呼び出された場合
- list.html をテンプレートに利用
- $users 配列に設定したデータを 'list' という名前でテンプレートエンジンに渡す
- /hello のパスを list という名前で記録しておく
/hello/{name} で呼び出された場合
- profile.html をテンプレートに利用
- パスの{name}の場所のデータを、 'name' という名前でテンプレートエンジンに渡す
- /hello/{name} のパスを profile という名前で記録しておく
テンプレートの作成
Twigのサンプルテンプレートを準備して、ルートに対応させます。
レイアウトテンプレートの作成
ユーザー一覧ページとプロフィールページのひな形となるレイアウト layout.html を作成します。
- /templates フォルダー内に layout.html を作成
- 以下のコードを書く
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>SlimPHP Twig Test-{% block title %}{% endblock %}</title> </head> <body> <h1>{% block pagetitle %}{% endblock %}</h1> <div id='content'> {% block content %} {% endblock %} </div> <hr /> <div id='footer'> © Copyright 2016 by YuTanaka </div> </body> </html>
- {% block <ブロック名> %}から{% endblock %}までの箇所を、他のテンプレートで指定した内容に差し替えることが可能
- 以下のようなブロックを定義している。list.htmlとprofile.htmlの {% block ・・・%} で囲んだ範囲が置きかわる
- title ブロック
- pagetitle ブロック
- content ブロック
ユーザー一覧ページ用のテンプレートの作成
- /templates フォルダー内に list.html を新規に作成
- 以下のTwigテンプレートコードを入力
{% extends "layout.html" %} {% block title %}User List{% endblock %} {% block pagetitle %}User List{% endblock %} {% block content %} <ul> {% for item in list %} <li><a href="{{ path_for('profile', {'name': item}) }}">{{item}}</a></li> {% endfor %} </ul> {% endblock %}
詳細ページ用のテンプレートの作成
- /templates フォルダー内に profie.html を新規に作成
- 以下のTwigテンプレートコードを入力
{% extends "layout.html" %} {% block title %}Profile{% endblock %} {% block pagetitle %}{{name}}'s Profile{% endblock %} {% block content %} <p>これは「{{name}}」のプロフィールです。</p> <p><a href="{{ path_for('list') }}">一覧へ</a></p> {% endblock %}
- layout.html を継承することを宣言
- タイトルにProfileを設定
- ページタイトルに、渡された name プロパティと、続けて 's Profile を設定
- content ブロックでは、「name プロパティのプロフィールです。」と表示する段落と、一覧に戻るリンクを設定
- 一覧へ戻るためのリンクは、listのルートをそのまま使う
テスト
準備ができたら、PHPの組み込みサーバーを起動して、動作を確認します。
- サーバーを起動
php -S 0.0.0.0:8080 -t public public/index.php
- ブラウザーで http://0.0.0.0:8080/hello にアクセス
- 一覧が表示されるのを確認
- 任意の名前をクリック
- クリックした名前のプロフィールが表示されることを確認
- 「一覧へ」をクリックして、一覧ページに戻ることを確認