Smartyを使うとき、DBからデータを配列で取得し、ループで回してテーブルを作成する、と言う処理が一番多いのではないでしょうか。そんなループ処理の1つとして{section}関数がSmartyにはあります。
Smartyを使うとき、DBからデータを配列で取得し、ループで回してテーブルを作成する、と言う処理が一番多いのではないでしょうか。そんなループ処理の1つとして{section}関数がSmartyにはあります。
{section}関数の形式と各属性は下記のようになります。
{section name=counter loop=$array_data start=2 step=2 max=10} {if $smarty.section.counter.first} {* 最初のループ時にtrueになります *} 最初のデータ {/if} {if $smarty.section.counter.last} {* 最後のループ時にtrueになります *} 最後のデータ {/if} {$smarty.section.counter.index} {* 現在のループインデックス Zero Originです。*} {$smarty.section.counter.index_prev} {* 前ループのインデックス値 *} {$smarty.section.counter.index_next} {* 次ループのインデックス値 *} {$smarty.section.counter.iteration} {* 現在のループ回数 1 Originです。*} {$smarty.section.counter.rownum} {* 現在のループ回数 1 Originです。(iterationと同じ) *} {$smarty.section.counter.loop} {* 最後のインデックス値 *} {$smarty.section.counter.total} {* ループした回数 *} {$array_data[counter]} {* 配列の値 *} {sectionelse} データが無いよ。 {/section}
{section}のloop属性に配列名(例えばloop=$array_data)を、name属性に適当な名前(例えばname=counter)を付けて、{$array_data[counter]}のような形でループするデータにアクセスします。
loopには数字をセットする事もできるので、セットした数字だけループさせる処理も可能です。
{section name=counter loop=10} 10回表示するぞ。<br/> {/section}
例えば、プログラム上で、下記のようにアサインされていた場合、各属性の値はこのようになります。
$Smarty->assign('array_data',range('a','z'));
多次元配列の場合、配列と連想配列で参照方法が異なるので例をあげておきます。
// 配列をセット $data1 = array(1000,1001,1002); $smarty->assign('data1',$data1); //配列をアサイン // 多次元配列をセット $data2 = array( array('a',1000), array('b',1002), array('c',1003), array('d',1004), ); $smarty->assign('data2',$data2); //多次元配列をアサイン // 連想配列をセット $data3 = array( array('id'=>1,'name'=>'foo'), array('id'=>2,'name'=>'bar'), array('id'=>3,'name'=>'hoge'), array('id'=>4,'name'=>'moge') ); $smarty->assign('data3',$data3); //連想配列をアサイン // 連想配列をセット $data4 = array( "a" => array('id'=>1,'name'=>'foo'), "b" => array('id'=>2,'name'=>'bar'), "c" => array('id'=>3,'name'=>'hoge'), "d" => array('id'=>4,'name'=>'moge') ); $Smarty->assign('data4',$data4); //連想配列をアサイン
テンプレート側では、次のように参照します。
<h2>配列data1の出力</h2> {section name=row loop=$data1} data: {$data1[row]}<br /> {/section} <h2>多次元配列data2の出力</h2> {section name=row loop=$data2} {* 多次元配列は$data2[row][0] または $data2[row].0 でアクセスできます。 *} data: {$data2[row][0]} {$data2[row].1}<br /> {/section} <h2>連想配列data3の出力</h2> {section name=row loop=$data3} {* 連想配列は$data3[row].id でアクセスできます。 ($data3[row][id]ではアクセスできません。) *} data: {$data3[row].id} {$data3[row].name}<br /> {/section} <h2>連想配列data4の出力</h2> {section name=row loop=$data4} {* 配列の添字が全て文字列の連想配列は{foreach}関数を使う必要があります。 *} data: {$data4[row].id} {$data4[row].name}<br /> {/section} <h2>データが無い場合</h2> {section name=row loop=$data5} data: {$data5[row].id} {$data5[row].name}<br /> {sectionelse} {* $data5が無い場合は {sectionelse}が実行されます。 *} データがありません。<br /> {/section}
テーブルを表示させる場合、smartyには{html_table}関数があるのですが、結構癖があるので{section}などでデータをループさせながら、テーブルを作成する方法が一般的かなと思います。
まず、テーブルに表示するデータを用意する必要がありますが、今回はなんちゃって個人情報と言う、「偽個人情報ジェネレータ」のデータを使用して見たいと思います。
でもって、上記のサイトで作成したデータをCVS形式で出力したものがdummy_data.csvです。このファイルをプログラム側で読込み、テンプレート側に渡してテーブルを作成します。
プログラムでは、fgetcsv関数でdummy_data.csvを読込み、$data変数に配列で格納します。
if(!$handle = fopen("dummy_data.csv", "r")){
echo "Cannot open file (dummy_data.csv)";
exit;
}
// csvファイルの読込み
while (($data[] = fgetcsv($handle, 1000, ",")) !== FALSE);
fclose($handle);
$Smarty = new MySmarty();
$Smarty->assign('title',"テーブル作成");
$Smarty->assign('data',$data);
$Smarty->display('section3.tpl');
渡されたデータの最初には、タイトル情報が入っているので、最初のループではテーブルヘッダ部分(<thead>)を作成します。2番目以降は普通のデータなので<tbody>の中にデータを表示します。
<table class="mytable"> {section name=counter loop=$data} {if $smarty.section.counter.first} {* 最初のデータはデータタイトルなので、タイトル作成 *} <thead> <tr> {* タイトルデータの配列を sectionでループ *} {section name=h_counter loop=$data[counter]} <th>{$data[counter][h_counter]}</th> {/section} </tr> </thead> <tbody> {else} {* 二番目以降は普通のデータ *} <tr class="{cycle values='add,even'}"> {* cycle を使用して列の色を変化させる *} {* データの配列を sectionでループ *} {section name=h_counter loop=$data[counter]} <td>{$data[counter][h_counter]}</td> {/section} </tr> {/if} {/section} </tbody> </table>
{section}は、PHPのfor文と同じような使い方も可能なので、これを利用して日付ラジオボックスを作ってみます。
プログラムは、特にやることはないです。
$Smarty = new MySmarty(); $Smarty->assign('title',"日付ラジオボックス作成"); $Smarty->display('section4.tpl');
テンプレートでは下記のことをしています。
これ以外に、ラジオボックスの横に表示する日付を{$smarty.section.time.index|jp_date_format:'%Y年%m月%d日(%a)'}として表示しています。
smartyには、幾つかの変数修飾子があり、その中にunixタイムスタンプを指定した形式にフォーマットしてくれるdate_formatがあります。しかし、date_formatは曜日の表示が日本語に対応しておらず、英語表記で表示されてしまいます。
これを日本語表記に対応させたjp_date_formatを作った方がおられたので、これを使用させてもらっています。
{section name=time start=$smarty.now loop=$smarty.now+604800 step=86400} <label> <input type="radio" name="date" value="{$smarty.section.time.index}"> {$smarty.section.time.index|jp_date_format:'%Y年%m月%d日(%a)'} </label> {/section}