第13回 次世代のSmarty - Smarty3の紹介 - Smarty講座

yossy先生のSmarty講座

Lecutures on PHP

第13回 次世代のSmarty - Smarty3の紹介 (その2)

 このエントリーをはてなブックマークに追加

テンプレートで新たに出来ること

続いてテンプレートに関する変更点を2つ紹介します。

◎ テンプレートにPHPコードが使えるようになった

yossy先生
1つめはテンプレートにPHPのコードを使うことが出来るようになった、ということです。

もちろん今までのタグベースのテンプレートも使うことが出来ます。しかしそれだけではなく、PHPのコードをテンプレートとして使いたいというニーズに、Smarty3では応えたことになります。

ではどのように切り替えるか、というと、PHP側でテンプレートを呼び出す際に「リソース」を指定します。

$smarty->display('php:mytemplate.tpl');

display()の引数でテンプレートファイルを指定しますが、そのファイル名の前に「php:」という文字列がありますね。

これが「リソース」で「php:」を指定するとテンプレートをPHPのコードとして認識します。
指定がなければ(もしくは「file:」を指定した場合)、従来のタグベースのテンプレートとして解釈します。

PHPのコードをテンプレートとする場合、Smartyはコンパイルを実行しません。そのままPHPのコードとして実行します。

もう一つ「string:」というリソースも用意されています。これはその後の文字列をテンプレートとして解析します。

$smarty->display('string:This is my template, {$foo}!');

さて、PHPコードのテンプレートの話に戻します。PHPコードのテンプレートでも修飾子や関数も使うことが出来ます。

修飾子は変数のメソッドとして使用します。

<?=$foo->escape('html')?>

PHPコードのテンプレートに渡された変数の実態は、PHP_Variable_Objectというクラスのインスタンスになります。
なので、テンプレートに文字列を渡したとしても、その変数の実態はオブジェクトなのでメソッドを呼ぶことが出来るのです。
内部的にはPHP_Variable_Objectクラスに__toString()というクラスメソッドが用意されており、表示時にはこのメソッドが呼ばれ文字列に変換された結果が返されます。

そして修飾子の連結も出来ます。メソッドを続けて呼ぶことが出来ます。

<?=$foo->truncate(5)->escape('html')?>

関数を呼ぶ場合は、ちょっと特殊で$_fという関数ハンドラが用意されています。このハンドラのメソッドとして呼び出します。

<?=$_f->time()?>
<?=$_f->time()->truncate(2)?>

◎ テンプレートに新しい文法が追加

yossy先生
けどSmartyを使うなら、やっぱりタグベースのテンプレートを使いたいよね、という人も多いと思います。

そんな人のためにも、Smarty3では多くの変更点が用意されています。ここでは、2つめのテンプレートの変更点として、一気に新文法を紹介します。




○ テンプレートタグに計算式が書けるようになりました。

{$x+$y}

PHP関数も計算式に使うことが出来ます。

{assign var=foo value=2*(3+sqrt($bar))}

○ {assign}で配列を定義することが出来るようになりました。

{assign var=foo value=[1,2,3]}
{assign var=foo value=['y'=>'yellow','b'=>'blue']}
{assign var=foo value=[1,[9,8],3]}

○ {assign}を使わなくても変数に値を設定することが出来るようになりました。

{$foo=$bar+2}

○ 配列変数へのアクセスで、"."だけでなく"[]"で指定出来るようになりました。従来の'.'を使うことも出来ます。

{$foo['colour']}
{$foo.colour}

○ 変数名の指定に変数を使うことができるようになりました。

{$foo_{$x}}

上記の例では、$xの値が「1」だったとき、「$foo_1」という変数の値が表示されます。

○ オブジェクトのメソッド連結が使えるようになりました。

{$object->method1($x)->method2($y)}

○ ループを書くための新タグ{for}が追加されました。

Smarty3でも{foreach}{section}ともサポートはするようですが、置き換わっていく方針のようです。
{for}の使い方には2種類あります。1つめは、配列の要素を順に取得する方法です。

{assign var=hoge value=[a,b,c,d,e]}
{for $v in $hoge}
    {$v}
{/for}

このとき、{for}の中で特殊な変数を使うことが出来ます。

$var@key => 配列のキー
$var@iteration => ループの順番(1から連番)
$var@total => 配列の要素数
{assign var=hoge value=[a,b,c,d,e]}
{for $v in $hoge}
    aaa = {$v} / {$v@key} / {$v@iteration} / {$v@total}<br />
{/for}

もう一つはCなどでもおなじみの方法です。セミコロンで区切って初期条件、ループ終了条件、繰り返し後の処理を指定します。複数の式をカンマで区切って記述することも可能です。

{for $x=0, $y=count($foo); $x<$y; $x++}  ....  {/for}

○ ループを書くための新タグ{while}も追加されました。

{while $i<10}  ....  {/while}

{for}と併せて、ループ処理が非常に書きやすくなりますね。

○ テンプレート上で、キャッシュをさせないセクションを宣言する新タグ{nocache}が追加されました。

{nocache} ... {/nocache}

これは変数や関数結果の属性としても指定可能です。

{$foo nocache=true}

yossy先生
個人的には、{for}{while}などのループ処理の改善と{assign}の配列指定対応が大きな改善点かなと思っています。
バージョン2の時にこうなればいいのになーと思っていた、かゆいところに手が届くような修正がSmarty3では組み込まれています。

  



Pick Up Q&A

Q
ログファイルの中の空のデータ行を削除したい
 このエントリーをはてなブックマークに追加 
A
ログのデータ個数(列数)が固定で、空のログが"<><><>"だと既知であれば if ($line === "<><><>") { continue; } で読み飛ばしてもいいのでは? ...

>>続きを読む

まずは配列や文字列の扱いから、じっくり勉強して行きましょう。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)