テンプレートエンジン (PHP Smarty) プログラム演習5

ウエブプログラムで厄介な点の一つは、デザイン(UI/HTML)部分のコーディングがプログラム内部のロジックに混入するすることで可読性が低下するだけでなく、メンテナンス性が落ちるケースが多々あることです。また、UIはHTML/CSS技術として一つの技術体系があるため、ウエブデザイナーとしても分業されているケースもあります。そうなると、プログラムとデザインの(ソース上の)分離が必要になります。それを実現する手段としてテンプレートエンジンがあり、PHPではSmartyと呼ばれるライブラリが一般的に利用されています。今回は少し本題と外れますが、このテンプレートエンジンの利用をマスターしましょう。
Smartypearで提供されるライブラリではないため、本家のサイトからダウンロードします。ダウンロードしたファイルを展開すると、たくさんのファイルが展開されますが、
とありますが、実際に利用するのは Smarty-2.x.x/lib 以下です このlib を php の include_path で参照できる場所ににコピーします

MAMPの場合は
bash-3.2$ cp -r libs /Applications/MAMP/bin/php5/lib/php/Smarty

これで

require_once('Smarty/Smarty.class.php');

でライブラリを読み込むことができます。簡単な例として、課題1で開発したPHPサイトをSmarty対応してみます。プログラム部分は以下のようになります。

bash-3.2$ cat prog5/index.php
<?php
    require_once('Smarty/Smarty.class.php');
    error_log('script start');

    $smarty = new Smarty();
    $smarty->template_dir = './template/';
    $smarty->compile_dir  = './template/cache';

    $templateParams = array();
    $templateParams['query'] = $_GET['query'];
    $templateParams['scriptname'] = basename($_SERVER['SCRIPT_NAME']) ;

    $smarty->assign('p', $templateParams);
    $smarty->display('smarty_sample.tpl');

    error_log('query=' . $_GET['query']);
    error_log('script end');

    exit;

?>

テンプレート部分は以下になります

bash-3.2$ cat prog5/template/smarty_sample.tpl 
<html>
<head>
<title>Sample Program 5 php-1</title>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8">
</head>
<body>

<form action="./{$p.scriptname}">
<input type="text" name="query" value="{$p.query}">
<input type="submit" value="search">
</form>

</body>
</html>

プログラム部分でSmartyのクラスとインスタンス化します。

$smarty = new Smarty();

次に、テンプレートの保存場所、また、一度読み込まれたテンプレートは中間コードとしてcacheされるのでその保管場所を指定します(apacheから書き込みできる権限を与えてあらかじめ作成しておく)。

$smarty->template_dir = './template/';
$smarty->compile_dir  = './template/cache';

今回はプログラム直下にディレクトリを作りましたが、本来であればapacheのDocumentRootから外れた場所の方が望ましいです)
次にSmartのテンプレートに渡す変数をラベルとともにassignします。ラベルは複数assin可能で1ラベルごとに1変数とできますが、プログラムとテンプレートの変数受け渡しの仕様を明確にする上で1つのラベルで1つのHASH変数(複数変数)とする形を私はよくとります。

$smarty->assign('p', $templateParams);

最後に、displayではテンプレートを指定すると変数をテンプレートに割当て出力まで行います。

$smarty->display('smarty_sample.tpl');

テンプレート内から変数にアクセスする場合は ラベルを用いてアクセスします。この場合はラベルがHASHなので

{$p.scriptname}
{$p.query}

でそれぞれ値を取り出すことが可能です。

以上のようにHTMLの記述部分がプログラム本体と分離していることが分かります。デザインの変更はテンプレートファイルの修正のみで対応できます。Smartyにはその他たくさんの機能があり柔軟なテンプレート制御が可能です(条件分や繰り返し文,プラグインなど)。使い方によってはテンプレート内である程度のロジックも組めるのでそれを利用するのも有効です。

perlでも同じようにテンプレートエンジンとして

があります。
テンプレートエンジンは理解するまで多少は苦労ですが、覚えておくと非常に有効なのでこの時点でぜひマスターしてください。

【演習】
ウエブ検索アプリケーションで作成したプログラムをHTMLテンプレートを用いいて書き換えてみましょう。