「WordPressで学ぶPHP(2)データ構造(配列・オブジェクト)編」を発売しました。
本書は「WordPressで学ぶPHP(1)変数・制御構造編」の続編にあたり、PHPの「データ構造」(配列とオブジェクト)について解説します。
配列やオブジェクトは、頭の中で考えるだけでは、イメージがつかみにくいです。本書では図を多用して、配列やオブジェクトをなるべく分かりやすく解説することを心がけました。
Kindle本で、定価250円です。
月曜始まりのカレンダーを出力する(完成編)
昨日の話の続きで、月曜始まりのカレンダーを出力する方法をお話しします。
今日は、昨日述べた問題点の解決方法と、具体的なテンプレートについて解説します。
1.1日が日曜日の場合
まず、1日が日曜日の場合に、1日をカレンダーに出力する方法から述べます。
1日が日曜日の場合、MTCalendarタグの繰り返しの1回目では、1日の日付を出力する状態になり、空のセルの出力ではありません。
そこで、「繰り返しの1回目であり、かつ空のセルでないならば、1日の日付を出力する」というように条件判断するようにします。
昨日あげたテンプレートでは、繰り返しの1回目を判断する処理が入っています。
そこで、そのMTIfタグのブロックの中に、空のセルでないかどうかを判断して、出力を分ける処理を追加します。
2.月の最後の日が日曜日の場合
次に、月の最後の日が日曜日の場合の方法です。
月の最後の日が日曜日である場合、MTCalendarタグそのものの動作では、その後の月曜日に空のセルを出力する状態になります。
この場合、月の最後の日の次の月曜日を出力する段階では、以下の3つの条件をすべて満たします。
- 日付の出力をすでに行っている
- 空のセルを出力する状態になっている
- 月曜日のセルを出力する状態になっている
そこで、上記の3つの条件をすべて満たす場合は、それ以後の空のセルを出力しないようにします。
上記のうち、2番目と3番目の条件の判断は、昨日紹介したテンプレートの中ですでに行っていますので、1番目の条件を判断する処理を追加します。
この条件は、「day_shown」という変数で判断できるようにします。
MTCalendarタグのブロックに入る前に、変数day_shownには0を代入しておきます。
そして、日付を出力した時点で、変数day_shownの値を1に変えます。
3.テンプレートを修正する
ここまでの話に基づいて、昨日作ったテンプレートを修正すると、以下のようになります。
背景が水色になっている行を追加しています。
<$mt:SetVar name="day_shown" value="0"$> <$mt:SetVar name="null_week" value="0"$> <table border="1"> <tr><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th><th>日</th></tr> <mt:Calendar> <mt:CalendarIfBlank> <$mt:SetVar name="blank" value="1"$> <mt:Else> <$mt:SetVar name="blank" value="0"$> </mt:CalendarIfBlank> <mt:CalendarIfEntries> <$mt:SetVar name="entries" value="1"$> <mt:Else> <$mt:SetVar name="entries" value="0"$> </mt:CalendarIfEntries> <mt:CalendarIfNoEntries> <$mt:SetVar name="no_entries" value="1"$> <mt:Else> <$mt:SetVar name="no_entries" value="0"$> </mt:CalendarIfNoEntries> <$mt:CalendarCellNumber setvar="cell_num"$> <mt:SetVarBlock name="week_flag"><$mt:GetVar name="cell_num" op="%" value="7"$></mt:SetVarBlock> <mt:If name="week_flag" eq="2"> <$mt:SetVar name="week_header" value="1"$> <mt:Else> <$mt:SetVar name="week_header" value="0"$> </mt:If> <mt:If name="week_flag" eq="1"> <$mt:SetVar name="week_footer" value="1"$> <mt:Else> <$mt:SetVar name="week_footer" value="0"$> </mt:If> <mt:If name="cell_num" eq="1"> <mt:If name="blank"> <mt:Else> <tr> <td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td> <mt:If name="entries"> <td><mt:Entries lastn="1"><a href="<$mt:EntryPermalink$>"><$mt:CalendarDay$></a></mt:Entries></td> <mt:Else> <td><$mt:CalendarDay$></td> </mt:If> <$mt:SetVar name="day_shown" value="1"$> </tr> </mt:If> <mt:Else> <mt:If name="day_shown"> <mt:If name="blank"> <mt:If name="week_header"> <$mt:SetVar name="null_week" value="1"$> </mt:If> </mt:If> </mt:If> <mt:Unless name="null_week"> <mt:If name="week_header"> <tr> </mt:If> <mt:If name="blank"> <td> </td> </mt:If> <mt:If name="entries"> <td><mt:Entries lastn="1"><a href="<$mt:EntryPermalink$>"><$mt:CalendarDay$></a></mt:Entries></td> <$mt:SetVar name="day_shown" value="1"$> </mt:If> <mt:If name="no_entries"> <td><$mt:CalendarDay$></td> <$mt:SetVar name="day_shown" value="1"$> </mt:If> <mt:If name="week_footer"> </tr> </mt:If> </mt:Unless> </mt:If> </mt:Calendar> <mt:Unless name="null_week"> <td> </td> </tr> </mt:Unless> </table>
追加した部分の内容は、以下の通りです。
3-1.1行目
月の最後の日が日曜日かどうかを判断するために、「日付をすでに出力した」ということを表す変数が必要です(2項)。
この情報は、「day_shown」という名前の変数に保存することにします。
1行目では、変数day_shownの値を0にして、初期値では「日付をまだ出力していない」という状態にします。
3-2.2行目
月の最後の日が日曜日の場合は、MTCalendarタグによってカレンダーの月曜日以後に出力される空白のセルを、出力しないようにすることが必要です。
そこで「月の最後の日が日曜日で、月曜日以降は出力しない」ということを、「null_week」という名前の変数に保存することにします。
2行目では、変数null_weekの値を0にして、初期値では「月の最後の日が日曜日ではない」という状態にします。
3-3.34~44行目
33行目のMTIfタグによって、MTCalendarタグの繰り返しの1回目の時に、この部分が処理されます。
まず、34行目のMTUnlessタグで、これから出力するセルが空白(=変数blankの値が1)でないかどうかを判断します。
空白でないなら、それは1日の日曜日であることになりますので、その日の情報を出力します。
36行目で、日曜日の前の月曜日~土曜日の空白を出力した後、37行目以降で1日の日曜日の情報を出力します。
1日に記事があれば、37行目の条件が成立して、38行目に進みます。
そして、MTCalendarDayタグによって「1」の数字が出力され、その部分が1日の記事へのリンクになります。
一方、1日に記事がない場合は、39行目のMTElseタグ以降に進み、「1」の数字だけが出力されます。
最後に、42行目のMTSetVarタグで、変数day_shownの値を1にし、「日付を出力した」ということを表す状態にします。
3-4.47~53行目
2項で述べたように、月の最後の日が日曜日の時に、空の行が出力されないようにすることも必要です。
そこで、以下の3つの条件を判断し、それらをすべて満たしているときには変数null_weekの値を1に変えて、「これから出力するのは空の行である」ということを表すようにします。
- 日付の出力をすでに行っている
- 空のセルを出力する状態になっている
- 月曜日のセルを出力する状態になっている
3-5.54/72行目
これから出力するのが空の行ではない(変数null_weekの値が1でない)かどうかを判断し、空でないときだけ、55行目~71行目を処理するようにします。
これによって、カレンダーの後に空の行が出力されることを防ぎます。
3-6.63/67行目
カレンダーの最後に空の行を出力しないようにするために、「日付を出力した」ということを記憶しておく必要があります(2項参照)。
そこで、MTCalendarDayタグで日付を出力した後には、変数day_shownの値を1に変えておきます。
3-7.75/78行目
月曜始まりにすると、カレンダーの最後の日曜日の空白のセルが出力されないので、MTCalendarタグの後に空白のセルを1つ出力するようにしていました。
しかし、月の最後の行が空になる場合、空白のセルも出力してはなりません。
そこで、最後の週が空の行でなかった場合(=変数null_weekの値が1でなかった場合)だけ、空白のセルを出力するようにします。