MTで公開日が現在から最も近い未来の記事を表示する

この週末、Movable Typeで公開日が現在から最も近い未来の記事を表示できないか検討しました。具体的には、博物館や公園のWebサイトのホームで次の休日のイベントをピックアップして表示するようなパターンです。

昨年末に公開した「MTでカスタムフィールドのLIKEフィルタやX以上・Y未満のフィルタを実現する」を使っても実現できますが、シンプルに公開日でフィルタができないかと考えました。テンプレートを書くと次のようになります。

<$mt:Date format="%Y%m%d" setvar="tmp.today"$>
<$mt:SetVar name="tmp.today" value="000000" append="1"$>
<mt:Entries limit="1" authored_on_filter="$tmp.today" sort_order="ascend">
<$mt:EntryBody$>
</mt:Entries>

その後フィルタを適用するコードをどう書くのか調べたのですが、野田さんが書かれていた非公開にしている記事を抽出可能にするフィルタのプラグイン「mt-plugin-mtentries-status-filter」を最近見たことを思い出し、それが参考になるかと試しました。結果、次のコードで意図した動作になりました。

name: MTEntriesAuthoredOnFilter
id  : MTEntriesAuthoredOnFilter
key:  mtentriesauthoredonfilter
version: 1.0.0
tags:
  filters:
    Entries:
      authored_on_filter:
        handler: >
          sub {
            my ( $ctx, $args, $cond ) = @_;
            my $terms = $ctx->{ terms };
            my $authored_on_filter = $args->{ authored_on_filter };
            if ( $authored_on_filter ) {
              $terms->{ authored_on } = { op => '>=',
                                          value => $authored_on_filter
                                        };
              $terms->{ id } =  { op => '>',
                                  value => 0,
                                };
            }
          }

念のためMySQLのクエリログを取ってみてみましたが、こちらも意図したクエリになっています。

SELECT entry_id
FROM mt_entry
WHERE (entry_id > '0') AND (entry_blog_id = '1') AND (entry_authored_on >= '2016-03-28 00:00:00') AND (entry_class = 'entry') AND (entry_status = '2')
ORDER BY entry_authored_on ASC, entry_id ASC
LIMIT 1

あとはcronで./tools/rebuild-pages --user=cron-builder --pass=p@ssw0rd --blog_id=1 --type=index --silentのようにrebuild-pagesを実行すれば良いでしょう。追加で必要なモジュールはcpanmなどで入れても良いですし、/path/to/mt/extlibに手動で入れても動きました。cron-builderユーザーは、サイトの再構築のみを許可したユーザーです。

この記事のタグ