「WordPressで学ぶPHP(2)データ構造(配列・オブジェクト)編」を発売しました。
本書は「WordPressで学ぶPHP(1)変数・制御構造編」の続編にあたり、PHPの「データ構造」(配列とオブジェクト)について解説します。
配列やオブジェクトは、頭の中で考えるだけでは、イメージがつかみにくいです。本書では図を多用して、配列やオブジェクトをなるべく分かりやすく解説することを心がけました。
Kindle本で、定価250円です。
リストを一定件数ずつ区切って出力する
FacebookのMovable Type勉強会のグループに、「フォルダの一覧を4つずつ区切って、ul/li要素のリストで出力したい」というような内容の質問がありました。
この事例のように、各種のオブジェクトのリストを、一定件数ずつに区切って出力したいことは、よくあることです。
この方法を紹介します。
1.考え方
質問の事例では、リストを4件ずつ区切りたいということでした。
このような場合、まず繰り返しの回数を数え、それを4で割った余りを求めます。
繰り返しが1回進むごとに、余りは以下のようになります。
繰り返し 回数 | 余り |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
4 | 0 |
5 | 1 |
6 | 2 |
7 | 3 |
8 | 0 |
9 | 1 |
10 | 2 |
11 | 3 |
12 | 0 |
13 | 1 |
... | ... |
4個ずつ区切る場合、各グループの最初は、繰り返しの1回目、5回目、9回目・・・になります。
これらの場合、繰り返し回数を4で割った余りは、上の表より常に1です。
したがって、「繰り返し回数を4で割った余りが1」という条件を満たす時に、グループの最初だけで出力すべき内容を出力するようにします。
同様に、各グループの最後は、繰り返しの4回目、8回目、12回目・・・になります。
これらの場合、繰り返し回数を4で割った余りは、上の表より常に0です。
したがって、「繰り返し回数を4で割った余りが0」という条件を満たす時に、グループの最後だけで出力すべき内容を出力するようにします。
ただ、リストに出力する個数が4の倍数になっていない場合、最後のグループでは、グループの最後に出力すべき内容が出力されなくなります。
リストに出力する個数が4の倍数でない場合、繰り返しを終えた時点で、繰り返し回数を4で割った余りは、上の表より0以外の値になります。
そこで、繰り返し終了後に余りが0以外であれば、グループの後に出力すべき内容を出力します。
2.テンプレートの組み方のパターン
上記の考え方に沿って、リストの出力を一定件数ずつ区切る場合のテンプレートの組み方を一般化すると、以下のようになります。
なお、繰り返し回数と余りは、それぞれctrとmodという変数に代入しています。
<$mt:SetVar name="ctr" value="1"$> <繰り返し系のブロックタグ> <$mt:SetVar name="mod" value="$ctr"$> <$mt:SetVar name="mod" op="%" value="区切る件数"> <mt:If name="mod" eq="1"> グループの最初に出力する内容 </mt:If> 個々のオブジェクトを出力する処理 <mt:If name="mod" eq="0"> グループの最後に出力する内容 </mt:If> <$mt:SetVar name="ctr" op="++"$> </繰り返し系のブロックタグ> <mt:If name="mod" ne="0"> グループの最後に出力する内容 </mt:If>
1行目のMTSetVarタグでは、繰り返しの回数を1に初期化します。
3行目と4行目で、繰り返し回数を区切る件数で割った余りを、変数modに求めます。
また、12行目のMTSetVarタグで、繰り返しが1回進むごとに、変数ctrの値を1ずつ増やします。
5~7行目は、余りが1の時に、グループの最初の時だけ、オブジェクトの前に何かを出力する処理です。
また、9~11行目は、余りが0の時に、グループの最後の時だけ、オブジェクトの後に何かを出力する処理です。
そして、最後の14~16行目は、余が0でない(=リストの個数が件数の倍数でない)時に、グループの最後の時の内容を出力する処理です。
3.フォルダのリストの出力
上記の話に沿って、トップレベルのフォルダのリストを、4件ずつ区切ってul/li要素で出力するテンプレートを組むと、以下のようになります。
なお、個々のli要素には、グループ内の1番目~4番目のそれぞれに、List01~List04のクラスを振るようにしています。
<$mt:SetVar name="ctr" value="1"$> <mt:TopLevelFolders> <$mt:SetVar name="mod" value="$ctr"$> <$mt:SetVar name="mod" op="%" value="4"$> <mt:If name="mod" eq="1"> <ul> </mt:If> <li class="List0<mt:If name="mod" eq="0">4<mt:Else><$mt:GetVar name="mod"$></mt:If>"><$mt:FolderLabel$></li> <mt:If name="mod" eq="0"> </ul> </mt:If> <$mt:SetVar name="ctr" op="++"$> </mt:TopLevelFolders> <mt:If name="mod" ne="0"> </ul> </mt:If>
li要素のクラスの出力が複雑ですが、この部分を分解して書くと、以下のようになります。
class="List0 <mt:If name="mod" eq="0"> 4 <mt:Else> <$mt:GetVar name="mod"$> </mt:If> "
グループの1回目~3回目までは、List01~List03のクラスを振ります。
これらの時には、余り(変数mod)の値が1~3になりますので、「List0」の後に余りの値をそのまま出力します(5行目のMTGetVarタグ)。
一方、グループの4回目では、List04のクラスを振ります。
この場合、余りの値は0になっていますので、余りをそのまま出力すると「List00」になってしまいます。
そこで、MTIfタグで余りが0かどうかを判断し(2行目のMTIfタグ)、0の時は「4」を出力します(3行目)。
4.変数や条件判断は必須
この例のように、手の込んだ処理をしようとすると、変数や条件判断を避けて通ることができません。
拙著「Movable Type 5.1 Webサイト製作ガイドVolume 2」では、変数や条件判断について、かなり詳しく解説しています。
「変数や条件判断がよく分からない」という方は、ぜひ拙著をお読みください。