今月/来月の記事一覧を出力する(前編)

MTQで以下のような質問が上がっていました。

ウェブサイトテンプレートで、ブログの今月の記事と来月の記事を表示する方法がわからないです。

すでにまーしーさんが解答していますが、私も答えてみます。

1.今月を得る

まず、今月を「201202」のような形で得て、変数this_monthに代入することから始めます。
後で今月かどうかを条件判断する際に、この変数を使います。

現在(正確には、最後に再構築した時)は、MTDateタグで得ることができます。
このタグにformatモディファイアを指定して「yyyymm」の形に変換すると、今月を得ることができます。
その値を変数this_monthに代入します。
実際にテンプレートタグを書くと、以下のようになります。

<$mt:Date format="%Y%m" setvar="this_month"$>

2.来月を得る

次に、変数this_monthの値に1を足し、来月を得て、変数next_monthに代入します。
後で来月かどうかを条件判断する際に、この変数を使います。

ただ、今月が12月である場合、単に変数の値を1増やすだけだと、「201213」のように13月になってしまいます。
そこで、変数next_monthの値の最後が「13」になっている場合は、年を1つ増やし、月を「01」にします。

この処理を書くと、以下のようになります。

<$mt:GetVar name="this_month" op="++" setvar="next_month"$>
<mt:If name="next_month" like="13$">
  <$mt:Date format="%Y" setvar="next_year"$>
  <$mt:GetVar name="next_year" op="++" setvar="next_month"$>
  <$mt:SetVar name="next_month" append="1" value="01"$>
</mt:If>

まず、1行目のMTGetVarタグで、変数this_monthの値に1を足し、変数next_monthに代入します。

次に、2行目のMTIfタグで、変数next_monthの最後が「13」になっているかどうかを調べます。
likeモディファイアは、変数の値を正規表現で比較する働きをします。
「$」は「値の最後」を意味しますので、「13$」で「値の最後が13」という意味になります。

MTIfタグの条件が成立した時には、3~5行目が実行されます。
まず、3行目のMTDateタグで、今年の年を取り出し、変数next_yearに代入します。
次に、4行目のMTGetVarタグで、変数next_yearの値に1を足し、変数next_monthに代入します。
そして、5行目のMTSetrVarタグで、変数next_monthの最後に「01」を連結します。

3.月ごとに記事をまとめて出力する

月ごとに記事をまとめて出力するには、MTArchiveListタグとMTEntriesタグを組み合わせて、以下のように書きます。

<mt:ArchiveList archive_type="Monthly">
  ・
  ・(各種の処理)
  ・
  <mt:Entries>
    ・
    ・(個々のブログ記事の内容を出力する処理)
    ・
  </mt:Entries>
  ・
  ・(各種の処理)
  ・
</mt:ArchiveList>

また、ウェブサイト内のテンプレートで、特定のブログの記事を月ごとにまとめて出力するなら、上記の部分を<mt:Blogs include_blogs="ブログのID">~</mt:Blogs>のタグで囲みます。

4.今月か来月を判断する

今取り上げている例では、アーカイブの月が今月か来月の時だけ、MTEntriesタグの部分を出力するようにします。
したがって、「アーカイブの月が今月か来月」という条件判断(MTIfタグ)で、MTEntriesタグの部分を囲みます。

MTIfタグでは、「2つの条件のどちらかを満たした時」という処理を、残念ながらスマートに書くことができません。
このような処理は、以下の形で書きます。

  • フラグ用の変数に0を代入します。
  • 1つ目の条件を判断し、条件を満たしていたら、フラグ用の変数の値を1にします。
  • 2つ目の条件を判断し、条件を満たしていたら、フラグ用の変数の値を1にします。
  • 2つの条件のどちらかを満たせば、上の2つの処理の結果、フラグ用変数の値が1になっています。そこで、「フラグ用変数の値が1」という条件で、処理を分けます。

変数archive_monthに、アーカイブの月を代入するものとします。
この場合だと、以下のようにすることで、今月または来月のアーカイブの時だけ、ブログ記事の一覧を出力することができます。

<$mt:ArchiveDate format="%Y%m" setvar="archive_month"$>
<$mt:SetVar name="flag" value="0"$>
<mt:If name="archive_month" eq="$this_month">
  <$mt:SetVar name="flag" value="1"$>
<mt:Else name="archive_month" eq="$next_month">
  <$mt:SetVar name="flag" value="1"$>
</mt:If>
<mt:If name="flag">
・
・(ブログ記事の一覧を出力する処理)
・
</mt:If>

1行目のMTArchiveDateタグで、アーカイブの年月を得て、formatモディファイアで「201201」のような形にして、変数archive_monthに代入します。
2行目では、MTSetVarタグを使って、フラグ用の変数(flag)の値を0にします。
3行目のMTIfタグで、変数archive_monthが、変数this_monthの値と等しければ、4行目のMTSetVarタグで変数flagを1にします。
また、5行目のMTElseタグで、変数archive_monthが、変数next_monthの値と等しければ、6行目のMTSetVarタグで変数flagを1にします。

これで、変数archive_monthが、変数this_month/next_monthのどちらかと等しければ(=アーカイブの月が今月か来月であれば)、変数flagの値が1になります。
そこで、7行目のMTIfタグで変数flagの値が1かどうかを判断し、その時(=アーカイブの月が今月か来月)だけ、ブログ記事の一覧を出力するようにします。

5.ひとまず完成

ここまでの話から、完成したテンプレートは以下のようになります。
なお、ブログのIDが2番であると仮定しています(9行目の「include_blogs="2"」)

<$mt:Date format="%Y%m" setvar="this_month"$>
<$mt:GetVar name="this_month" op="++" setvar="next_month"$>
<mt:If name="next_month" like="13$">
  <$mt:Date format="%Y" setvar="next_year"$>
  <$mt:GetVar name="next_year" op="++" setvar="next_month"$>
  <$mt:SetVar name="next_month" append="1" value="01"$>
</mt:If>

<mt:Blogs include_blogs="2">
<mt:ArchiveList archive_type="Monthly">
  <$mt:ArchiveDate format="%Y%m" setvar="archive_month"$>
  <$mt:SetVar name="flag" value="0"$>
  <mt:If name="archive_month" eq="$this_month">
    <$mt:SetVar name="flag" value="1"$>
  <mt:Else name="archive_month" eq="$next_month">
    <$mt:SetVar name="flag" value="1"$>
  </mt:If>
  <mt:If name="flag">
    <h2><$mt:ArchiveDate format="%Y/%m"$></h2>
    <mt:Entries>
    <div>
      <h3><$mt:EntryTitle$></h3>
      <$mt:EntryBody$>
    </div>  
    </mt:Entries>
  </mt:If>
</mt:ArchiveList>
</mt:Blogs>

6.問題点

ここまででほぼ動作しますが、1つ問題点があります。

MTArchiveListタグは、ブログ記事がないアーカイブは処理しません。
そのため、来月に記事がないと、来月の記事については一切処理が行わません。
結果として、来月に記事がなく、今月の記事だけがある時は、今月の記事だけが出力されます。

同様に、今月に記事がなく、来月の記事だけがある場合は、来月の記事だけが出力されます。
さらに、今月/来月とも記事がないと、何も出力されません。

質問された方は、記事がない場合は、「記事がありません」のように出力したいとのことでした。
この問題を解決する方法は、明日の記事で述べたいと思います。