こんにちは、さるまりんです。
繰り返し処理をしていて、いま何回めの繰り返しかを知りたい時、ありませんか?
例えば表を作成している時に3行ごとに区切りをつけたい場合。
例えば単語の配列を持っていて「、」で区切り最後だけ「。」をつけたい場合。
Smartyで画面を作っている時に思ったのでメモしておきます。
Smarty foreachのカウンター
いま何回め?を知りたい時はindexもしくはiterationを使います。
indexは0スタート、iterationは1スタートです。
サンプルです。
表にindexとiterationを表示して、3行ごとに境界を太く緑にすることで区切りをつけてみます。
$citiesとCSSは次のように準備しているものとします。
$cities = [
'札幌',
'仙台',
'東京',
'横浜',
'名古屋',
'大阪',
'神戸',
'福岡',
];
CSS
td.border-row {
border-style: solid;
border-bottom-width: 3px;
border-bottom-color: #00ff00;
}
Smartyで次のように実装すると
<table>
<tr>
<th>No.</th>
<th>index</th>
<th>都市</th>
</tr>
{foreach name=loop from=$cities item=city}
<tr>
<td{if $smarty.foreach.loop.iteration%3 == 0} class="border-row"{/if}>{$smarty.foreach.loop.iteration}</td>
<td{if $smarty.foreach.loop.iteration%3 == 0} class="border-row"{/if}>{$smarty.foreach.loop.index}</td>
<td{if $smarty.foreach.loop.iteration%3 == 0} class="border-row"{/if}>{$city}</td>
</tr>
{/foreach}
</table>
以下の表が出力されます。
| No. | index | 都市 |
|---|---|---|
| 1 | 0 | 札幌 |
| 2 | 1 | 仙台 |
| 3 | 2 | 東京 |
| 4 | 3 | 横浜 |
| 5 | 4 | 名古屋 |
| 6 | 5 | 大阪 |
| 7 | 6 | 神戸 |
| 8 | 7 | 福岡 |
foreachで$citiesの配列に対して繰り返し処理をします。繰り返しの名前はnameで指定したloop、繰り返し内での要素はcityです。
1カラム目では$smarty.foreach.loop.iterationで何回目かを、2カラム目では$smarty.foreach.loop.indexでインデックスを、3カラム目には配列に格納されている都市名を表示しています。
iterationを3で割ったあまりがない時(=3の倍数ですね)にcssを当てることによって、区切りの境界の表示を変えています。
最初と最後は特別
上の例では3行ごとというのをiterationを3で割ったあまりが0かどうかで判断していました。
1行目はiterationが1(もしくはindexが0)、最終行はiterationが配列の要素数(もしくはindexが配列の要素数-1)と一致するかどうかで判断できます。
が、このチェックのためには特別な仕組みが用意されています。
firstとlastです。
上の例はこの二つを使って次のように書き換えることができます。
{foreach name=loop from=$cities item=city}
{if $smarty.foreach.loop.first}
<table>
<tr>
<th>No.</th>
<th>index</th>
<th>都市</th>
</tr>
{/if}
<tr>
<td{if $smarty.foreach.loop.iteration%3 == 0} class="border-row"{/if}>{$smarty.foreach.loop.iteration}</td>
<td{if $smarty.foreach.loop.iteration%3 == 0} class="border-row"{/if}>{$smarty.foreach.loop.index}</td>
<td{if $smarty.foreach.loop.iteration%3 == 0} class="border-row"{/if}>{$city}</td>
</tr>
{if $smarty.foreach.loop.last}
</table>
{/if}
{/foreach}
最初に$smarty.foreach.loop.firstを使って最初の行かを判断しています。firstとlastは一致するとtrueと評価されます。なのでifを使って、繰り返しの初回だけ<table>や見出しの行を出力しています。最後は$smarty.foreach.loop.lastで最終行かを判断して閉じる</table>タグを出力しています。
冒頭で例にあげた$citiesの配列を「、」区切り、最後だけ「。」として表示するには次のように記述します。
{foreach name=loop from=$cities item=city}
{$city}{if $smarty.foreach.loop.last}。{else}、{/if}
{/foreach}
$cityの後に最後は「。」それ以外は「、」を出力しています。
こんな風に出力されます。
札幌、仙台、東京、横浜、名古屋、大阪、神戸、福岡
他にもスマートなやり方があるんでしょうね〜。
いっぱい勉強します!
読んでくださってありがとうございます。
ではまた!