月曜始まりのカレンダーを出力する(完成編)

昨日の話の続きで、月曜始まりのカレンダーを出力する方法をお話しします。
今日は、昨日述べた問題点の解決方法と、具体的なテンプレートについて解説します。

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>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</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>&nbsp;</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>&nbsp;</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でなかった場合)だけ、空白のセルを出力するようにします。