最近変化があった順にブログ記事を出力する

MTQで、以下の日付でブログ記事を並べ替えて出力したいという質問を見ました。

  • コメントがないブログ記事は、その記事の更新日時
  • コメントがあるブログ記事は、最近コメントがついた日時

この処理は、標準のテンプレートタグとハッシュを組み合わせれば可能です。
その方法を紹介します。
なお、上記の2つのどちらかに該当するブログ記事を、本記事では「最近変化があったブログ記事」と呼ぶことにします。

1.考え方

最近変化があった日時順にブログ記事を一発で並べる方法は、残念ながら標準機能にはありません。
ただ、以下のような手法で並べ替えることが可能です。
なお、最近変化があったブログ記事を5件出力したいものとします。

  • 1.最近更新されたブログ記事を5件取り出し、そのIDと更新日時をハッシュに代入します。
    ハッシュのキーをブログ記事のIDにし、値を更新日時にします。
    また、値(更新日時)は、数値順で並べ替えられるように、年月日時分秒を連結した14桁の数値にします。
  • 2.最近コメントがあったブログ記事を5件取り出し、そのIDと最新コメントの投稿日時を、上と同じハッシュに代入します。
  • 3.ハッシュを値(日時)の降順で並べ替え、それに対応するキー(ブログ記事のID)を、順に5件取り出します。
  • 4.ブログ記事のIDから、そのブログ記事を読み込んで、必要な情報を出力します。

例えば、最近更新されたブログ記事5件のIDと更新日時が、以下の表のようになっているとします。

ID更新日時
1052010年7月25日0時0分0秒
1042010年7月20日0時0分0秒
1032010年7月15日0時0分0秒
1022010年7月10日0時0分0秒
1012010年7月5日0時0分0秒

また、最近コメントがあったブログ記事5件のIDとコメントの投稿日時が、以下の表のようになっているとします。

ID更新日時
542010年7月23日0時0分0秒
1022010年7月18日0時0分0秒
532010年7月13日0時0分0秒
522010年7月8日0時0分0秒
512010年7月3日0時0分0秒

まず、最近投稿されたブログ記事から、上記の手順1でハッシュを作ると、以下のようになります。

キー
10520100725000000
10420100720000000
10320100715000000
10220100710000000
10120100705000000

次に、最近コメントがついたブログ記事から、ハッシュの続きを作ります。
IDが102番のブログ記事は、最近投稿された記事にも入っていますが、最新のコメントの日時の方が新しいので、ハッシュの値が更新されます。
したがって、ハッシュの内容は以下のようになります。

キー
10520100725000000
10420100720000000
10320100715000000
10220100718000000
10120100705000000
5420100723000000
5320100713000000
5220100708000000
5120100703000000

このハッシュを値で並べ替えると、以下のようになります。

キー
10520100725000000
5420100723000000
10420100720000000
10220100718000000
10320100715000000
5320100713000000
5220100708000000
10120100705000000
5120100703000000

次に、並べ替えた結果のハッシュの先頭から、5件を取り出します。すと、そのキーが、最近変化があったブログ記事のIDになります。

2.ハッシュを作る処理をテンプレート化する

ここまでの話に沿って、ハッシュを作る処理をテンプレート化すると、以下のようになります。

<mt:Entries sort_by="modified_on" lastn="5">
  <$mt:EntryModifiedDate format="%Y%m%d%H%M%S" setvar="ts"$>
  <$mt:EntryID setvar="entry_id"$>
  <$mt:SetVar name="ts_hash" key="$entry_id" value="$ts"$>
</mt:Entries>
<mt:Entries recently_commented_on="5">
  <mt:Comments lastn="1">
    <$mt:CommentDate format="%Y%m%d%H%M%S" setvar="ts"$>
  </mt:Comments>
  <$mt:EntryID setvar="entry_id"$>
  <$mt:SetVar name="ts_hash" key="$entry_id" value="$ts"$>
</mt:Entries>

前半の5行は、最近更新されたブログ記事5件からハッシュを作る処理です。
1行目のMTEntriesタグで、「sort_by="modified"」と「lastn="5"」のモディファイアを指定していますので、最近更新されたブログ記事を5件読み込みます。
2行目では、更新日時(MTEntryModifiedDateタグ)を14桁の数値に変換して、変数tsに代入します。
3行目では、ブログ記事のID(MTEntryIDタグ)を変数entry_idに代入します。
そして、4行目のMTSetVarタグで、「ts_hash」という名前のハッシュに、ブログ記事のID(変数entry_id)がキー、値が更新日時(変数ts)の要素を追加します。

後半の6行目以降は、最近コメントがあったブログ記事5件からハッシュを作る処理です。
6行目のMTEntriesタグでは、「recently_commented_on="5"」のモディファイアを指定していますので、最近コメントがあったブログ記事を5件読み込みます。
次に、7~9行目のMTCommentsタグのブロックで、個々のブログ記事についた最新のコメントの日付を、変数tsに代入します。
そして、残りの部分でハッシュts_hashに要素を追加します。

3.ブログ記事を出力する

ここまででハッシュができましたので、そのハッシュから先頭5件の要素を取り出し、そのキーからブログ記事のIDを得て、個々のブログ記事の情報を出力します。
その処理をテンプレートタグで表すと、以下のようになります。

<mt:Loop name="ts_hash" sort_by="value reverse">
  <mt:If name="__counter__" le="5">
    <mt:Entries id="$__key__">
      ブログ記事の情報を出力する部分
    </mt:Entries>
  </mt:If>
</mt:Loop>

まず、1行目のMTLoopタグで、ハッシュts_hashを値の逆順(=日付の新しい順)に並べ替え、要素を1つずつ取り出します。
次の2行目では、繰り返し回数(変数__counter__)の値が5以下の時だけ、ブログ記事の情報を出力するようにしています。
ハッシュには、「最近投稿されたブログ記事」と「最近コメントがあったブログ記事」の情報5件ずつ入れていて、最大で10件のブログ記事の情報が入っているので、その中の先頭5件だけを取り出すために、このMTIfタグが必要です。
そして3行目では、ハッシュのキー(=変数__key__)の値からブログ記事のIDを割り出して、MTEntriesタグでそのブログ記事を読み込んでいます。

4.ちなみに

ここまでで述べた例の他にも、ハッシュを使うといろいろなことができます。
しかし、ハッシュはプログラム的な考え方なので、難しいという声もよく聞きます。
 
拙著「Movable Type 5 Webサイト製作ガイドVolume 2」では、変数/条件判断/配列/ハッシュ/繰り返しなど、テンプレートタグでプログラム的な記述をする方法も詳細に解説しています。
ハッシュ等が苦手だという方は、この本もぜひお読みください。