こんにちは、okutani(@okutani_t)です。今回はPHPのテンプレートエンジンである「Smarty」の導入方法について見ていきましょう。
Smartyを使うと処理部と出力部を分けることができるので、デザイナーの仕事とエンジニアの仕事を分かりやすくすることができます。
Smartyは利用するサーバーにひとつあればOKですが、本記事では「Smarty本体をダウンロードしてプロジェクトに直接設置する」方法で話を進めていきます。
また、ローカルでSmartyを使う場合はPHPが動く環境が必要です。WindowsならXAMPP、MacならMAMPを使うと楽にPHPのローカル開発環境が構築できて便利です。
ではさっそくSmartyの導入手順を見ていきましょう。
スポンサーリンク
Smartyのダウンロード
下記(GitHub)サイトからSmartyをダウンロードしてきます。
LINKsmarty-php/smarty · GitHub
「Download ZIP」をクリック。
「smarty-master.zip」がダウンロードされます。解凍しましょう。
この中にある「libs」がSmartyの本体です。このlibsを「smarty」にリネームし、利用したいプロジェクトファイルに丸ごと移動させましょう。
Smartyで必要なファイルの準備
ダウンロードとリネームが済んだので、Smartyで利用するファイルを作成して初期設定を行いましょう。
プロジェクトファイル直下に「templatesディレクトリ」「templates_cディレクトリ」「index.php」をそれぞれ作成します。「comnディレクトリ」は.cssや.jsを設置する場所として、お好みで作成してみてください。
なお、templates_cディレクトリのパーミッションは「777」にしておく必要があります。各自、FTPソフト等でアップロードする際には忘れずに設定しておきましょう。パーミションの変更方法は各種FTPソフトの設定方法に従ってください。
作成した各ディレクトリは次の役割を持ちます。
・templates(テンプレートファイルを格納する)ディレクトリ
・templates_c(コンパイルされたファイルが格納される)ディレクトリ
次に、テンプレートファイルを作成します。「index.tpl」をtemplatesディレクトリ内に作成。
各ディレクトリとファイルの役割をまとめておきます。次のとおりです。
- smarty
- templates
- templates_c
- ~.php
- ~.tpl
- comn
Smarty本体が格納されているディレクトリ
テンプレートファイルを格納
Smartyでコンパイルされたファイルを保存。コンパイルは自動で行われる(要パーミッション設定:777)
行いたいPHPの処理をここに書く。~.phpが処理したデータをテンプレートに渡す
表示したい表側(主にHTML)を記述する。PHP側の処理結果を出力する
「.css」「.js」「img」等のファイルを格納。お好みで作成
では、index.phpとindex.tplに試しにコードを書いてみましょう。
index.phpとindex.tplにサンプルコードを記述
index.php(処理側)に次のようにコードを記述してみましょう。今回はsmartyディレクトリ内に予め用意されている「Autoloader.php」を使ってSmartyを読み込むようにしました。なお、このAutoloader.phpはGitHubのリポジトリでのみ提供されています。
<?php // smartyの設定ファイル読み込み require_once(realpath(__DIR__) . "/smarty/Autoloader.php"); Smarty_Autoloader::register(); $name = 'okutani'; $obj = new StdClass(); $obj->hello = 'こんにちは!'; $smarty = new Smarty(); $smarty->assign('name', $name); $smarty->assign('obj', $obj); $smarty->display('index.tpl');
index.tplは次のとおりです。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Smartyテスト</title> <link rel="stylesheet" href="comn/style.css"> </head> <body> {* ここはコメントです *} やあ、{$obj->hello} {$name} </body> </html>
上記のようにindex.phpで処理を行い、「assign()」で処理の結果をテンプレートファイルに渡します。テンプレートファイルの読み込みは「display()」で行います。
index.tplで処理の結果を受け取り、「{$hoge}」のようにすることで結果を出力することができます。上記の例のようにオブジェクト、配列等もassignすることができます。
なお、{$hoge}と波括弧のみで使うと、JavaScriptやCSSで使っている波括弧と重複して、エラーになってしまいます。その場合は、後述する独自のSmartyクラスで再定義するか、次のようにliteralで囲ってあげる必要があります。
<script> {literal} function hello(){ alert("hi");} {/literal} </script>
テンプレート側でのSmartyを使ったコメントは「{* piyo *}」のように書きます。HTMLコメントの「<!– huga –>」と違い、検証ツールでソースコードを表示してもコメントは表示されない、という特徴があります。
では出力結果を確認してみましょう。
出力結果の確認
ブラウザで「index.php」を開いてみましょう。次のように出力されていればOKです。
Smartyを使ってブラウザに「こんにちは!」と「okutani」を表示することができました。
このままでも十分、今までより便利にPHPを扱うことができますが、独自のSmartyクラスを実装することでより使いやすくなります。
次の項目ではSmartyクラスを継承して、独自のSmartyクラスを作成する方法を見ていきます。
独自のSmartyクラスを作ってみる
次のように、独自のSmartyクラスを作成してみました。設置場所はsmartyディレクトリ直下、名前は「CustomSmarty.class.php」としました。
※もっといい書き方があるかと思います…が、とりあえず下記の形で。
<?php require_once(realpath(__DIR__) . "/Autoloader.php"); require_once(realpath(__DIR__) . '/Smarty.class.php'); class CustomSmarty extends Smarty{ function __construct(){ parent::__construct(); $this->left_delimiter = '#{'; $this->right_delimiter = '}#'; Smarty_Autoloader::register(); } }
このように独自のSmartyクラスを定義することで、自分の好みの設定を外部ファイルにまとめて利用することができます。
今回は「left_delimiter」「right_delimiter 」を「#付き」で定義してみました。これにより、assignされた変数はテンプレート側で#{$hoge}#と展開します。
上記のようにdelimiterを再定義するか、{literal}{/literal}を使って処理するかはお好きな方を使ってください。私は#{$hoge}#の形で使っています。
上記をindex.phpファイルで読み込めば、拡張したSmartyクラスが利用できます。
<?php // smartyの設定ファイル読み込み require_once(realpath(__DIR__) . "/smarty/CustomSmarty.class.php"); $name = 'okutani'; $obj = new StdClass(); $obj->hello = 'こんにちは!'; $smarty = new CustomSmarty(); $smarty->assign('name', $name); $smarty->assign('obj', $obj); $smarty->display('index.tpl');
delimiterを再定義したので、index.tplは次のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Smartyテスト</title> <link rel="stylesheet" href="comn/style.css"> </head> <body> #{* ここはコメントです *}# やあ、#{$obj->hello}# #{$name}# </body> </html>
これでJavaScript・CSSとSmartyが競合を起こさないで済みますね。
このように独自のSmartyクラスを作成して、ご自身で使いやすいようにカスタマイズしていきましょう。
おまけ: サーバー上でstrftime()エラーが出る場合
さくらのレンタルサーバーにアップして動作確認したところ、次のエラーが出ました。
Warning: strftime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/xxxxx/www/smarty-basic-template/smarty/sysplugins/smarty_internal_templatecompilerbase.php on line 411
この場合、PHPで利用するタイムゾーンを設定してあげればOKです。strftime()を呼ぶ前に下記を追加するか、
date_default_timezone_set('Asia/Tokyo');
php.iniファイルに下記を書いてあげればOKです。
date.timezone = Asia/Tokyo
私はphp.iniファイルに「date.timezone = Asia/Tokyo」を記述して対応しました。さくらレンタルサーバーの場合、php.iniファイルは管理画面の「PHP設定の編集」から変更できます。参考にしてください。
まとめ
Smartyの導入と、独自のSmartyクラスを作成する手順を紹介しました。
個人でPHPを使って開発する場合でも、処理部と出力部をわけてコードが見やすくなるのでオススメですね。
初めて導入するときはすこし分かりにくいですが、本記事を参考にして便利にSmartyを使ってみてください。