月曜始まりのカレンダーを出力する(考え方編)

昨日、MTQに以下のような質問が上がっていました。

MT5を利用して、スケジュールカレンダーを作成しております。
デフォルトでは日曜になっている曜日始まりを
月曜に変更できたら、と思っているのですが、、
そのような方法はありますでしょうか?

残念ながら、Movable Typeの標準機能では、簡単に月曜始まりにすることはできません。
ただ、既存のカレンダー関係のテンプレートタグと、条件判断とをうまく組み合わせれば、月曜始まりのカレンダーを出力することができます。
今日は、その基本的な考え方を解説します。

1.MTCalendarタグの仕組み

Movable Typeでカレンダーを出力するには、MTCalendarタグや、その関連のテンプレートタグを使います。
MTCalendarタグは、日曜日始まりのカレンダーを出力するブロックタグで、繰り返しごとに日付を順に出力することができます。
また、MTCalendarタグでは、1日が日曜日でない場合は、日曜日から1日の前の日までの空のセルも出力されます。
さらに、月の最後の日が土曜日でない場合は、その次の日から土曜日までの空のセルも出力されます。

基本的には、以下のようにテンプレートタグを組むことで、1か月分のカレンダーを表組みで出力することができます。

<table>
  <tr><th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th></tr>
<mt:Calendar>
  <mt:CalendarWeekHeader><tr></mt:CalendarWeekHeader>
    <td>
    <mt:CalendarIfBlank>
      &nbsp;
    </mt:CalendarIfBlank>
    <mt:CalendarIfEntries>
      <mt:Entries lastn="1"><a href="<$mt:EntryPermalink$>"><$mt:CalendarDay$></a></mt:Entries>
    </mt:CalendarIfEntries>
    <mt:CalendarIfNoEntries>
      <$mt:CalendarDay$>
    </mt:CalendarIfNoEntries>
    </td>
  <mt:CalendarWeekFooter><tr></mt:CalendarWeekFooter>
</mt:Calendar>
</table>

4行目のMTCalendarWeekHeaderタグと、16行目のMTCalendarWeekFooterタグは、週の最初(日曜日)と最後(土曜日)を判断するタグです。
これらのタグで、週の初めに<tr>タグを出力し、週の終りに</tr>タグを出力して、表の1行分になるようにします。

6~8行目のMTCalendarIfBlankタグは、出力するセルが空のセルであるかどうかを判断し、その時に出力する内容を決めるタグです。
上の例では、7行目の&nbsp;で、空白を出力しています。

9~11行目のMTCalendarIfEntriesタグは、出力するセルが日付のセルで、かつその日にブログ記事があるかどうかを判断し、その時に出力する内容を決めるタグです。
上の例では、10行目によって、その日の日付を出力し、その部分をその日のブログ記事へのリンクにしています。

12~14行目のMTCalendarIfNoEntriesタグは、出力するセルが日付のセルで、かつその日にブログ記事がないどうかを判断し、その時に出力する内容を決めるタグです。
上の例では、13行目のMTCalendarDayタグで、その日の日付のみ出力しています。

2.月曜始まりにする基本的な考え方

MTCalendarタグを応用して月曜始まりのカレンダーを出力するには、基本的には以下のようにします。

2-1.最初のセルを出力しない

まず、MTCalendarタグの1回目の繰り返しでは、何も出力しないようにします。
1回目の繰り返しは、カレンダーの初めの日曜日のセルを出力する処理に当たります。
したがって、そこで何も出力しなければ、次の月曜日から出力することになります。

2-2.2回目以降の繰り返し

2回目以降の繰り返しでは、日曜始まりのカレンダーと同じように、日付を出力します。
ただし、行の先頭の<tr>タグと、行の終わりの</tr>タグは、それぞれ月曜日/日曜日に出力する必要があります。
通常のカレンダーでは、MTCalendarWeekHeader/MTCalendarWeekHeaderタグを使いましたが、これらのタグだと日曜日と土曜日を判断することになり、月曜始まりのカレンダーには使えません。
そこで、MTCalendarタグのブロック内の繰り返し回数を数え、その数によって月曜日と日曜日を判断するようにします。

繰り返しの回数は、「MTCalendarCellNumber」というテンプレートタグで得ることができます。
このタグの値と曜日の関係を見ると、以下のように変化します。

繰り返しの個々の回対応する曜日MTCalendarCellNumberタグの値
1回目日曜日1
2回目月曜日2
3回目火曜日3
.........
7回目土曜日7
8回目日曜日8
9回目月曜日9
10回目火曜日10
.........
14回目土曜日14
15回目日曜日15
16回目月曜日16
17回目火曜日17
.........

この表を見ると、月曜日のセルでは、MTCalendarCellNumberタグの値は2、9、16・・・となり、7で割った余りが2になっています。
また、日曜日のセルでは、MTCalendarCellNumberタグの値は1、8、15・・・となり、7で割った余りが1になっています。

したがって、「変数ctrを7で割った余りが2」と「変数ctrを7で割った余りが1」ということを判断すれば、月曜日と日曜日の判断を行うことができます。

2-3.繰り返しが終わった後の処理

MTCalendarタグは、日曜始まり/土曜終わりのカレンダーを出力します。
そのため、MTCalendarタグの繰り返しが終わった時点では、最後に出力されたのは土曜日のセルです。

しかし、月曜始まりのカレンダーだと、カレンダーの最後のセルは日曜日になります。
そこで、最後の日曜日の分の空のセルを別途出力する必要があります。

また、カレンダーの各行の最後の</tr>タグは、日曜日のセルの後に出力します。
ところが、MTCalendarタグでは、繰り返しの最後が土曜日です。
そのため、MTCalendarタグが終わった時点では、表の最後の行の</tr>タグはまだ出力されていない状態になります。

これらのことから、MTCalendarタグのブロックの後に、最後の日曜日の分の空のセルと、表の最後の行の</tr>タグを出力する処理が必要になります。

明日は、ここまでの話を元にして、具体的なテンプレートを組みます。
ただし、ここまでの話だけだと、まだ抜けている点がありますので、それも明日解説します。