フリーPHPスクリプト配布サイト。
Smartyは、PHP用のテンプレートエンジンです。これを利用すると、ロジックとデザインを分離して管理することができます。
一つのPHPファイルにロジックとデザインの両方を書いて作成することも可能ですが、分離することでプログラムの見通しが良くなります。また、プログラマーとデザイナーの分業など、複数の人が制作に関わる場合、特に威力を発揮します。
Smartyを利用するには、公式サイトからダウンロードしたファイルを、PHPから読み込める場所に設置します。その後、PHPプログラムから require_once 'libs/Smarty.class.php';
のように Smarty.class.php
を読み込めばOKです。(Smarty.class.php
がSmartyの本体です。)
Smartyの詳細な解説は、以下の公式ページに記載されています。
以下では、Smartyの基本的な使用方法を紹介します。なお、解説はSmarty3をもとに行っています。Smarty2では書き方が異なる箇所があります。
以下はSmartyを利用したサンプルです。コードの詳細な意味はともかく、まずは画面に文字を表示するだけのプログラムを作成してみます。
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$smarty->assign('test1', 'テスト1です。');
$smarty->assign('test2', 'テスト2です。');
$smarty->assign('test3', 'テスト3です。');
$smarty->display('test.html');
?>
今回はこのファイルの名前は sample.php
とします。このファイルに html
タグや body
タグを書く必要はありません。後ほど用意するテンプレートファイル内に書きます。
また、プログラムと同じフォルダ内に smarty
ディレクトリを作成し、その中にSmartyの libs
フォルダ内にあるファイルとディレクトリをすべてコピーします。
さらに、templates
ディレクトリと compile_dir
ディレクトリを作成します。レンタルサーバーで実行する場合、templates_c
ディレクトリには書き込み権限を与えておきます。
次にテンプレートを作成します。templates
内に test.html
を作成し、以下の内容を記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
<li>{$test1}</li>
<li>{$test2}</li>
<li>{$test3}</li>
</ul>
</body>
</html>
これで準備は完了です。PHPプログラムにアクセスすると、{$test1}
~ {$test3}
の部分がそれぞれ テスト1です。
~ テスト3です。
に置き換えられて表示されます。
このように、プログラム部分と表示部分を分割して作成することができるようになります。
なお、ファイルの構成は、一例ですが以下のようになります。
lesson / sample.php
|
+-- templates / test.html
|
+-- templates_c /
|
+-- smarty / debug.tpl
| Smarty.class.php
|
+-- plugins / ~略~
|
+-- sysplugins / ~略~
上で紹介したように、Smartyは Smarty.class.php
を読み込んでから使用します。このファイルに必要な命令が書かれているので、読み込むことによって色々な命令が利用できるようになります。
Smartyを使用するには、まずは Smarty
クラスを呼び出します。具体的には以下のようになります。
$smarty = new Smarty();
これで $smarty
にSmartyのオブジェクトが代入されます。以降はこのオブジェクトを参照することで、色々な操作ができるようになります。
template_dir
プロパティで、テンプレートを格納する場所を指定します。
この指定を行わなかった場合、templates/
を格納場所とみなします。ただし解りやすくするため、明示的にテンプレートの位置を指定したほうがいいでしょう。
compile_dir
プロパティで、コンパイル済みテンプレートを格納する場所を指定します。Smartyは毎回テンプレートファイルを解析せず、一度テンプレートを読み込むとPHPプログラムに変換(コンパイル)したものを保存します。次回からは変換済みのPHPプログラムを読み込むため、高速に動作します。
この指定を行わなかった場合、templates_c/
を格納場所とみなします。ただし template_dir
と同様、明示的にテンプレートの位置を指定したほうがいいでしょう。
もしプログラムやテンプレートを修正しても表示結果が変わらなかった場合、compile_dir
内のファイルをすべて削除してみてください。PHPプログラムへの変換が再度行われます。
assign
メソッドで、テンプレート上の変数に対して値を割り当てることができます。例えば
$smarty->assign('test1', 'テスト1です。');
と書くと、テンプレートの {$test1}
が テスト1です。
に置換されます。変数の割り当ては
$smarty->assign(array(
'test1' => 'テスト1です。',
'test2' => 'テスト2です。',
'test3' => 'テスト3です。'
));
このように array
で一度に行うこともできます。
display
メソッドで、テンプレートを読み込んで表示することができます。例えば
$smarty->display('test.html');
と書くと、template_dir
で指定した場所にある test.html
をテンプレートとして読み込み、表示します。表示の際、assign
で割り当てた変数が置換されます。
このように、Smartyを利用すればプログラム部分とデザイン部分を切り離して作成することができます。上のような短いブログラムの場合はあまりメリットが感じられないかもしれませんが、複雑なプログラムになってくると非常に有効になります。
assign
は変数だけでなく、配列を割り当てることもできます。
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$fruits = array('リンゴ', 'ミカン', 'ブドウ');
$smarty->assign('fruits', $fruits);
$smarty->display('test.html');
?>
テンプレート側では、{$fruits[0]}
や {$fruits[1]}
で配列の内容を参照することができます。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
<li>{$fruits[0]}</li>
<li>{$fruits[1]}</li>
<li>{$fruits[2]}</li>
</ul>
</body>
</html>
assign
は連想配列を割り当てることもできます。
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$fruits = array('apple' => 'リンゴ', 'orange' => 'ミカン', 'grape' => 'ブドウ');
$smarty->assign('fruits', $fruits);
$smarty->display('test.html');
?>
テンプレート側では、{$fruits.apple}
や {$fruits.orange}
で連想配列の内容を参照することができます。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
<li>{$fruits.apple}</li>
<li>{$fruits.orange}</li>
<li>{$fruits.grape}</li>
</ul>
</body>
</html>
Smartyでは、テンプレートに簡単な条件分岐や制御文を書くことができます。
Smartyを利用するのはロジックとデザインの分離が目的なので、テンプレートに複雑なロジックを書くのは本末転倒です。ですが、条件に応じて表示内容を切り替える場合など、デザインに関する簡単なロジックはテンプレート側で制御できると便利です。
以下は条件分岐の例です。
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$smarty->assign('sample', 10);
$smarty->display('test.html');
?>
あらかじめ sample
に 10
を割り当てています。特に新しい事はありません。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
{if $sample == 10}<p>変数sampleの内容は10です。</p>
{elseif $sample > 5}<p>変数sampleの内容は5より大きいです。</p>
{else}<p>変数sampleの内容は5より小さいです。</p>
{/if}
</body>
</html>
このように if
、elseif
、else
を使用することができます。比較の方法などはPHPと同じです。
Smartyでは処理の繰り返しも制御することができます。
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$fruits = array('リンゴ', 'ミカン', 'ブドウ');
$smarty->assign('fruits', $fruits);
$smarty->display('test.html');
?>
あらかじめ fruits
に 配列を割り当てています。特に新しい事はありません。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
{foreach $fruits as $fruit}
<li>{$fruit}</li>
{/foreach}
</ul>
</body>
</html>
これを実行すると、リンゴ
、ミカン
、ブドウ
がそれぞれリストで表示されます。
PHPの foreach
と同様、配列 $fruits
の内容が先頭から順に $fruit
という変数に代入され、繰り返し処理されていきます。
以下のようにすると、連想配列に対して繰り返し処理もできます。
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$fruits = array('apple' => 'リンゴ', 'orange' => 'ミカン', 'grape' => 'ブドウ');
$smarty->assign('fruits', $fruits);
$smarty->display('test.html');
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
{foreach $fruits as $key => $value}
<li>{$key} ... {$value}</li>
{/foreach}
</ul>
</body>
</html>
PHPの foreach
と同様、配列 $fruits
のキーと値が先頭から順に $key
と $value
という変数に代入され、繰り返し処理されていきます。
修飾子を使用すれば、assign
で割り当てた内容に変更を加えることができます。例えば
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$smarty->assign('test', "テスト。\nこれは<em>テスト</em>です。");
$smarty->display('test.html');
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<p>{$test}</p>
</body>
</html>
このようなプログラムとテンプレートがあった場合、{$test}
の内容は
テスト。
これは<em>テスト</em>です。
になります。ですが <br />
タグによる改行ではなく普通の改行なので、表示結果では改行が反映されません。
もし改行を反映させたければ、PHP側で nl2br
を使用すればOKです。ですがこのような表示に関する簡単な制御は、テンプレート側で指定できるようになっています。具体的には
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<p>{$test|nl2br}</p>
</body>
</html>
このように書きます。テンプレート側の変数名の後に |
を付け、さらに修飾子と呼ばれる命令を追加しています。nl2br
は改行を改行タグに変換する修飾子です。また、
<p>{$test|escape}</p>
のように escape
修飾子を指定すると、HTMLを無効にすることができます。修飾子を複数指定したい場合、
<p>{$test|escape|nl2br}</p>
と指定することができます。このように指定すると、先頭の修飾子から順に実行されていきます。また、
<p>{$test|default:'値はありません。'}</p>
このように default
という修飾子を指定すると、$test
に何も値が割り当てられていない場合に 値はありません。
と表示させることができます。:
に続いて、任意の文字列を指定することができます。
Smartyには、他にも色々な修飾子が実装されています。
修飾子を利用したければ、変数に対してその都度修飾子を指定します。ですが escape
などは不正な投稿を防ぐためにも、常に設定しておきたいです。
修飾子を毎回指定しても問題ないのですが、それでは少し面倒です。うっかり指定を忘れてしまう可能性もあります。
このような対策に、すべての変数に対して指定した修飾子を、常に適用させることができます。具体的には default_modifiers
というプロパティを使用します。
<?php
require_once 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir = 'templates_c/';
$smarty->default_modifiers = array('escape');
$smarty->assign('test', "テスト。\nこれは<em>テスト</em>です。");
$smarty->display('test.html');
?>
このように default_modifiers
に対して、配列の形式で修飾子を設定することができます。上の場合、Smartyにセットした値すべてに escape
修飾子が適用されます。
また、修飾子はいくつでも指定することができます。以下は escape
と nl2br
を指定した例です。
$smarty->default_modifiers = array('escape', 'nl2br');
もし部分的に default_modifiers
の指定を無効にしたければ、nofilter
を指定します。具体的には
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<p>{$test nofilter}</p>
</body>
</html>
このように指定すれば、$test
には default_modifiers
の指定が適用されません。
include
を使用すると、現在のテンプレートに他のテンプレートを読み込むことができます。例えば header.html
というテンプレートを作成し、以下の内容を述しておきます。
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
このテンプレートを読み込むには、以下のようにします。
<html>
{include file='header.html'}
<body>
<p>{$test}</p>
</body>
</html>
このようなテンプレートを作成すると、{include file='header.html'}
の部分が header.html
の内容に置き換わります。
現在のテンプレートで利用可能なすべての変数は、読み込まれたテンプレートでも利用することができます。これを利用すれば、全ページで共通のヘッダ部分を1つのファイルにまとめたりすることができます。
上手く利用すれば、テンプレートの修正を効率よく行うことができます。