2013.
09.
07
19:27:26
今回はSmartyにおいてテンプレート内で繰り返し処理を行うときのお話です。
for文相当の処理とwhile文相当の処理、
欲を言えばforeach文相当の処理もあると嬉しいかな。
それでは見ていきますかね。
まずは……Smaryさん特有のループ処理(--)b
「section」とかいう奴です。
一見するとfor文っぽいのですが、中身はfor文と全然違います。
基本的な書き方はこんなんφ(--)
「start」「loop」の設定値が回りくどい説明ですね。
細かい部分は後で見ていきます。
まずは基本的な使い方(--)b
例えばこんなコードを書くとφ(--)
■test.php
■test.tpl
こんな結果になりますφ(--)
ループ中のインデックス値を配列の添え字として使うには
「name」属性に指定した値(サンプルでは「hoge」)を書けば良いっぽいですね。
単独で表記したい場合は「$smarty.section.hoge.index」のように
一番上から書く必要があるみたいです。
「loop」には配列を指定するのが一般的な使い方です。
その配列の要素数分だけ繰り返してくれます。
まぁ配列を指定しないでこんな書き方もできますけどねφ(--)
■test2.tpl
個人的にはオススメはしませんが「loop」には整数値も指定できますよ。
一見するとfor文っぽいですが、詳しく見ていくと混乱することになります。
詳しくは後で見ていきますね。
またループ条件に入らない際の処理は「{sectionelse}」に書けます。
例えば「loop」に指定した配列が空の場合などですね。
こんなコードを書くとφ(--)
■test3.php
■test3.tpl
こんな結果になりますφ(--)
検索結果を一覧表示したい場合などに重宝しそうですね。
「{sectionelse}」に「検索結果がありません」とか書いておけば親切です。
さて、肩慣らしはそろそろ良いですか?
ここからがsectionさんの本番です(--)b
sectionさんでは各プロパティ値にアクセスできます。
書き方は
です。
プロパティには
があります。
よく分からないのもありますね(--ゞ
こんなテンプレートを書くとφ(--)
こんな結果になりますφ(--)
ここら辺までは一般的な解説サイトとかでも載っていますね。
「なんだ、簡単じゃん」と思いつつ私も読みました。
さて、それでは実際に使って……あれ?となったのが「start」と「loop」です(--)b
こいつら、for文と同じように考えると痛い目にあいます(-A-)
「start」で指定するのは要素の「インデックス値」です。
そしてマイナス指定の場合は、最後からの位置になります。
「loop」で指定するのは本来「配列」のようです。
それを踏まえてここからを読んでください。
例えばこんなテンプレートを書くとφ(--)
結果は
になります。
for文っぽいですね。
こんなテンプレートを書くとφ(--)
結果は
になります。
まだfor文っぽいですね。
しかしこんなテンプレートを書くとφ(--)
結果は
になります。
な、なんで?(--;
さらにこんなテンプレートを書くとφ(--)
結果は
になります。
もう訳わかんねーよ(TAT)
推測するにですね(--ゞ
loop=5
の「5」は
$ary = array();
$ary[0] = 0;
$ary[1] = 1;
$ary[2] = 2;
$ary[3] = 3;
$ary[4] = 4;
と同じなのだと思います。
同様に
loop=2
の「2」は
$ary = array();
$ary[0] = 0;
$ary[1] = 1;
と同じ。
そう考えて
を見ると、開始位置のインデックスは「-2」ですから
$ary[0] = 0;
$ary[1] = 1;
$ary[2] = 2;
$ary[3] = 3;
$ary[4] = 4;
の最後から2つ戻って
$ary[3] = 3;
が開始位置になります。
この位置を開始位置として「step=1」つまりインデックスを1ずつ増やす。
だから結果は
3, 4,
になるのでしょう。
の方も同様です。
$ary[0] = 0;
$ary[1] = 1;
の5番目のインデックスが開始位置ですが、配列の要素数がそんなにありません。
取りあえず一番デカい位置を開始位置にしとくー?ってな理由なのかよく分かりませんが
$ary[1] = 1;
が開始位置になり「step=-1」つまりインデックスを1ずつ減らす。
だから結果は
1, 0,
になるのでしょう。
本当はこんな指定(存在しないインデックスを開始位置に指定)しちゃ駄目だと思いますけどね。
まぁそんな感じの動きをするようです。
まとめるとですね(--)b
「loop」で処理対象の配列を指定し、
「start」でループ開始位置(のインデックス)を指定し、
「step」でループ毎の移動量を指定するのが「section」なようです。
あくまで繰り返すのは「loop」で指定した配列の中なのですね。
その他の繰り返し処理:for、while、foreach
for文相当の処理とwhile文相当の処理、
欲を言えばforeach文相当の処理もあると嬉しいかな。
それでは見ていきますかね。
まずは……Smaryさん特有のループ処理(--)b
「section」とかいう奴です。
一見するとfor文っぽいのですが、中身はfor文と全然違います。
基本的な書き方はこんなんφ(--)
{section name=section名 start=ループ開始のインデックス位置 loop=ループ回数を決めるための値 step=インデックス値の増分}
処理
{/section}
処理
{/section}
「start」「loop」の設定値が回りくどい説明ですね。
細かい部分は後で見ていきます。
まずは基本的な使い方(--)b
例えばこんなコードを書くとφ(--)
■test.php
<?php
//「Smarty.class.php」をインクルード
require_once(dirname(__FILE__) . '/smarty/libs/Smarty.class.php');
//インスタンス作成
$smarty = new Smarty();
//ディレクトリ指定
$smarty->template_dir = dirname(__FILE__) . "/templates";
$smarty->compile_dir = dirname(__FILE__) . "/templates_c";
$smarty->cache_dir = dirname(__FILE__) . "/cache";
$smarty->config_dir = dirname(__FILE__) . "/config";
//値設定
$ary = array("a", "b", "c", "d", "e");
$smarty->assign("val1", $ary);
//テンプレート表示
$smarty->display("test.tpl");
?>
//「Smarty.class.php」をインクルード
require_once(dirname(__FILE__) . '/smarty/libs/Smarty.class.php');
//インスタンス作成
$smarty = new Smarty();
//ディレクトリ指定
$smarty->template_dir = dirname(__FILE__) . "/templates";
$smarty->compile_dir = dirname(__FILE__) . "/templates_c";
$smarty->cache_dir = dirname(__FILE__) . "/cache";
$smarty->config_dir = dirname(__FILE__) . "/config";
//値設定
$ary = array("a", "b", "c", "d", "e");
$smarty->assign("val1", $ary);
//テンプレート表示
$smarty->display("test.tpl");
?>
■test.tpl
<html>
<head><title></title></head>
<body>
{section name=hoge start=0 loop=$val1 step=1}
{$smarty.section.hoge.index}:{$val1[hoge]}<br>
{/section}
</body>
</html>
<head><title></title></head>
<body>
{section name=hoge start=0 loop=$val1 step=1}
{$smarty.section.hoge.index}:{$val1[hoge]}<br>
{/section}
</body>
</html>
こんな結果になりますφ(--)
0:a
1:b
2:c
3:d
4:e
1:b
2:c
3:d
4:e
ループ中のインデックス値を配列の添え字として使うには
「name」属性に指定した値(サンプルでは「hoge」)を書けば良いっぽいですね。
単独で表記したい場合は「$smarty.section.hoge.index」のように
一番上から書く必要があるみたいです。
「loop」には配列を指定するのが一般的な使い方です。
その配列の要素数分だけ繰り返してくれます。
まぁ配列を指定しないでこんな書き方もできますけどねφ(--)
■test2.tpl
<html>
<head><title></title></head>
<body>
{section name=hoge2 start=0 loop=5 step=1}
{$smarty.section.hoge2.index}:{$val1[hoge2]}<br>
{/section}
</body>
</html>
<head><title></title></head>
<body>
{section name=hoge2 start=0 loop=5 step=1}
{$smarty.section.hoge2.index}:{$val1[hoge2]}<br>
{/section}
</body>
</html>
個人的にはオススメはしませんが「loop」には整数値も指定できますよ。
一見するとfor文っぽいですが、詳しく見ていくと混乱することになります。
詳しくは後で見ていきますね。
またループ条件に入らない際の処理は「{sectionelse}」に書けます。
例えば「loop」に指定した配列が空の場合などですね。
こんなコードを書くとφ(--)
■test3.php
<?php
//「Smarty.class.php」をインクルード
require_once(dirname(__FILE__) . '/smarty/libs/Smarty.class.php');
//インスタンス作成
$smarty = new Smarty();
//ディレクトリ指定
$smarty->template_dir = dirname(__FILE__) . "/templates";
$smarty->compile_dir = dirname(__FILE__) . "/templates_c";
$smarty->cache_dir = dirname(__FILE__) . "/cache";
$smarty->config_dir = dirname(__FILE__) . "/config";
//値設定
$smarty->assign("val2", array());
//テンプレート表示
$smarty->display("test3.tpl");
?>
//「Smarty.class.php」をインクルード
require_once(dirname(__FILE__) . '/smarty/libs/Smarty.class.php');
//インスタンス作成
$smarty = new Smarty();
//ディレクトリ指定
$smarty->template_dir = dirname(__FILE__) . "/templates";
$smarty->compile_dir = dirname(__FILE__) . "/templates_c";
$smarty->cache_dir = dirname(__FILE__) . "/cache";
$smarty->config_dir = dirname(__FILE__) . "/config";
//値設定
$smarty->assign("val2", array());
//テンプレート表示
$smarty->display("test3.tpl");
?>
■test3.tpl
<html>
<head><title></title></head>
<body>
{section name=hoge3 start=0 loop=$val2 step=1}
{$smarty.section.hoge3.index}:{$val1[hoge3]}<br>
{sectionelse}
値が無いよ<br>
{/section}
</body>
</html>
<head><title></title></head>
<body>
{section name=hoge3 start=0 loop=$val2 step=1}
{$smarty.section.hoge3.index}:{$val1[hoge3]}<br>
{sectionelse}
値が無いよ<br>
{/section}
</body>
</html>
こんな結果になりますφ(--)
値が無いよ
検索結果を一覧表示したい場合などに重宝しそうですね。
「{sectionelse}」に「検索結果がありません」とか書いておけば親切です。
さて、肩慣らしはそろそろ良いですか?
ここからがsectionさんの本番です(--)b
sectionさんでは各プロパティ値にアクセスできます。
書き方は
$smarty.section.name属性の値.プロパティ
です。
プロパティには
index:現在のループインデックス値
index_prev:前回のループインデックス値
index_next:次回のループインデックス値
iteration:ループの繰り返された回数(単純に何回回ったか)
first:最初のループでtrue、それ以外はfalse
last:最後のループでtrue、それ以外はfalse
rownum:「iteration」と同じ
loop:処理の終わりとなる(最後の)インデックス値
show:falseの場合はこのセクションが表示されない
total:ループしたトータル回数。{section} の外部でも使うことができる
index_prev:前回のループインデックス値
index_next:次回のループインデックス値
iteration:ループの繰り返された回数(単純に何回回ったか)
first:最初のループでtrue、それ以外はfalse
last:最後のループでtrue、それ以外はfalse
rownum:「iteration」と同じ
loop:処理の終わりとなる(最後の)インデックス値
show:falseの場合はこのセクションが表示されない
total:ループしたトータル回数。{section} の外部でも使うことができる
があります。
よく分からないのもありますね(--ゞ
こんなテンプレートを書くとφ(--)
<html>
<head><title></title></head>
<body>
{section name=hoge9 start=0 loop=3 step=1}
index:{$smarty.section.hoge9.index}<br>
index_prev:{$smarty.section.hoge9.index_prev}<br>
index_next:{$smarty.section.hoge9.index_next}<br>
iteration:{$smarty.section.hoge9.iteration}<br>
first:{$smarty.section.hoge9.first}<br>
last:{$smarty.section.hoge9.last}<br>
rownum:{$smarty.section.hoge9.rownum}<br>
loop:{$smarty.section.hoge9.loop}<br>
show:{$smarty.section.hoge9.show}<br>
total:{$smarty.section.hoge9.total}<br><br>
{/section}
</body>
</html>
<head><title></title></head>
<body>
{section name=hoge9 start=0 loop=3 step=1}
index:{$smarty.section.hoge9.index}<br>
index_prev:{$smarty.section.hoge9.index_prev}<br>
index_next:{$smarty.section.hoge9.index_next}<br>
iteration:{$smarty.section.hoge9.iteration}<br>
first:{$smarty.section.hoge9.first}<br>
last:{$smarty.section.hoge9.last}<br>
rownum:{$smarty.section.hoge9.rownum}<br>
loop:{$smarty.section.hoge9.loop}<br>
show:{$smarty.section.hoge9.show}<br>
total:{$smarty.section.hoge9.total}<br><br>
{/section}
</body>
</html>
こんな結果になりますφ(--)
index:0
index_prev:-1
index_next:1
iteration:1
first:1
last:
rownum:1
loop:3
show:1
total:3
index:1
index_prev:0
index_next:2
iteration:2
first:
last:
rownum:2
loop:3
show:1
total:3
index:2
index_prev:1
index_next:3
iteration:3
first:
last:1
rownum:3
loop:3
show:1
total:3
index_prev:-1
index_next:1
iteration:1
first:1
last:
rownum:1
loop:3
show:1
total:3
index:1
index_prev:0
index_next:2
iteration:2
first:
last:
rownum:2
loop:3
show:1
total:3
index:2
index_prev:1
index_next:3
iteration:3
first:
last:1
rownum:3
loop:3
show:1
total:3
ここら辺までは一般的な解説サイトとかでも載っていますね。
「なんだ、簡単じゃん」と思いつつ私も読みました。
さて、それでは実際に使って……あれ?となったのが「start」と「loop」です(--)b
こいつら、for文と同じように考えると痛い目にあいます(-A-)
「start」で指定するのは要素の「インデックス値」です。
そしてマイナス指定の場合は、最後からの位置になります。
「loop」で指定するのは本来「配列」のようです。
それを踏まえてここからを読んでください。
例えばこんなテンプレートを書くとφ(--)
{section name=hoge start=0 loop=5 step=1}
{$smarty.section.hoge.index},
{/section}<br>
{$smarty.section.hoge.index},
{/section}<br>
結果は
0, 1, 2, 3, 4,
になります。
for文っぽいですね。
こんなテンプレートを書くとφ(--)
{section name=hoge start=1 loop=5 step=1}
{$smarty.section.hoge.index},
{/section}<br>
{$smarty.section.hoge.index},
{/section}<br>
結果は
1, 2, 3, 4,
になります。
まだfor文っぽいですね。
しかしこんなテンプレートを書くとφ(--)
{section name=hoge start=-2 loop=5 step=1}
{$smarty.section.hoge.index},
{/section}<br>
{$smarty.section.hoge.index},
{/section}<br>
結果は
3, 4,
になります。
な、なんで?(--;
さらにこんなテンプレートを書くとφ(--)
{section name=hoge start=5 loop=2 step=-1}
{$smarty.section.hoge.index},
{/section}<br>
{$smarty.section.hoge.index},
{/section}<br>
結果は
1, 0,
になります。
もう訳わかんねーよ(TAT)
推測するにですね(--ゞ
loop=5
の「5」は
$ary = array();
$ary[0] = 0;
$ary[1] = 1;
$ary[2] = 2;
$ary[3] = 3;
$ary[4] = 4;
と同じなのだと思います。
同様に
loop=2
の「2」は
$ary = array();
$ary[0] = 0;
$ary[1] = 1;
と同じ。
そう考えて
{section name=hoge start=-2 loop=5 step=1}
{$smarty.section.hoge.index},
{/section}<br>
{$smarty.section.hoge.index},
{/section}<br>
を見ると、開始位置のインデックスは「-2」ですから
$ary[0] = 0;
$ary[1] = 1;
$ary[2] = 2;
$ary[3] = 3;
$ary[4] = 4;
の最後から2つ戻って
$ary[3] = 3;
が開始位置になります。
この位置を開始位置として「step=1」つまりインデックスを1ずつ増やす。
だから結果は
3, 4,
になるのでしょう。
{section name=hoge start=5 loop=2 step=-1}
{$smarty.section.hoge.index},
{/section}<br>
{$smarty.section.hoge.index},
{/section}<br>
の方も同様です。
$ary[0] = 0;
$ary[1] = 1;
の5番目のインデックスが開始位置ですが、配列の要素数がそんなにありません。
取りあえず一番デカい位置を開始位置にしとくー?ってな理由なのかよく分かりませんが
$ary[1] = 1;
が開始位置になり「step=-1」つまりインデックスを1ずつ減らす。
だから結果は
1, 0,
になるのでしょう。
本当はこんな指定(存在しないインデックスを開始位置に指定)しちゃ駄目だと思いますけどね。
まぁそんな感じの動きをするようです。
まとめるとですね(--)b
「loop」で処理対象の配列を指定し、
「start」でループ開始位置(のインデックス)を指定し、
「step」でループ毎の移動量を指定するのが「section」なようです。
あくまで繰り返すのは「loop」で指定した配列の中なのですね。
その他の繰り返し処理:for、while、foreach