いま何回目?Smartyの繰り返しカウンター

こんにちは、さるまりんです。

繰り返し処理をしていて、いま何回めの繰り返しかを知りたい時、ありませんか?

例えば表を作成している時に3行ごとに区切りをつけたい場合。

例えば単語の配列を持っていて「、」で区切り最後だけ「。」をつけたい場合。

Smartyで画面を作っている時に思ったのでメモしておきます。

Smarty foreachのカウンター

いま何回め?を知りたい時はindexもしくはiterationを使います。

index0スタート、iteration1スタートです。

サンプルです。

表にindexiterationを表示して、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行ごとというのをiteration3で割ったあまりが0かどうかで判断していました。

1行目はiteration1(もしくはindex0)、最終行はiterationが配列の要素数(もしくはindexが配列の要素数-1)と一致するかどうかで判断できます。

が、このチェックのためには特別な仕組みが用意されています。

firstlastです。

上の例はこの二つを使って次のように書き換えることができます。

{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を使って最初の行かを判断しています。firstlastは一致すると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の後に最後は「。」それ以外は「、」を出力しています。

こんな風に出力されます。

札幌、仙台、東京、横浜、名古屋、大阪、神戸、福岡

他にもスマートなやり方があるんでしょうね〜。

いっぱい勉強します!

読んでくださってありがとうございます。

ではまた!