PowerCMS 5で前後がリンクやPDFではない記事をEntryPrevious / EntryNextで出力したい

公開

PowerCMS 5、もしくはMovable Typeで企業サイトのお知らせを実装する際、記事一覧ページから直接どこかのページ・サイトにリンクしたり、PDF等のファイルにリンクしたりすることがあるかと思います。つまり記事本文がないケースがあるということです。その状況下で記事詳細ページに前後の記事へのリンクを設置しようとすると、EntryPrevious / EntryNextタグを使うものの、直接どこかのページ・サイトに飛ぶ記事・PDF等のファイルにリンクする記事は除きたい、ということになるかと思います。

MTEntriesをくるくる回して頑張る方法もあるかもしれませんが、「やはりお前らのMTMLは間違っている!」に該当します。テンプレートを書いた時は良いかもしれませんが、何年も運用を続けると再構築の速度が低下する可能性があるということです。

というわけでプラグインを書くことにします。既に「MTEntryNext,Previousの拡張(とか改良?とか)。 | Junnama Online」という記事があり、サンプルプラグインもあったのでこれを改変しました。

ロジックの検討

まず、PowerCMS 5であれば「管理画面カスタマイズ設定」、Movable TypeであればMTAppjQuery等を使用し、どこかのページ・サイトに飛ばす時、もしくはPDF等のファイルにリンクする時はカスタムフィールド「entry_include_prev_next」のチェックが外れるようにJavaScriptを書きました。テキストフィールドやアイテムのプレビューエリアを監視すれば上手くいきます。

次に「MT::Object->search_by_meta() でカスタムフィールド以外での検索条件を追加する - タケユー・ウェブ日報」を参考にし、search_by_metaでカスタムフィールド「entry_include_prev_next」が1である記事を抽出し、野田さんのプラグインに元からあるコードへIDの配列を渡すようにしました。

ただsearch_by_metaだけでやろうとすると、最新の記事ID = 最新の公開日でない場合にどうも上手く対応できませんでした。先に2月10日公開の記事を下書きし、次に2月5日公開の記事を公開した時にリンクが正しくないのです。公開日の秒を調整してもらうことで妥協してもらう、もしくはSQLを書くほかないと考えました。

require MT::Object;
my $driver = MT::Object->driver;
my $query = "SELECT `entry_meta_entry_id` FROM `mt_entry_meta`" .
    " JOIN `mt_entry` on `mt_entry_meta`.`entry_meta_entry_id` = `mt_entry`.`entry_id`" .
    " WHERE `entry_status` = " . MT::Entry::RELEASE() . " AND entry_blog_id = " . $current_entry->blog_id .
    " AND (`entry_meta_type` = 'field.entry_include_prev_next' AND `entry_meta_vinteger_idx` = 1)" .
    " AND ((`entry_authored_on` $gtlt_mark '" . MT::Object::_ts2db($current_entry->authored_on ) . "') OR" .
    " (`entry_authored_on` = '" . MT::Object::_ts2db($current_entry->authored_on ) . "' AND `entry_meta_entry_id` $gtlt_mark " . $current_entry->id . " ))" .
    " ORDER BY `entry_authored_on` $direction, `entry_id` $direction LIMIT 1";

PowerCMS Xほど得意でないのですが、恐らくこんな感じ。 LIMIT 1をたった今付けたけど大丈夫だったかと。これでEntryPrevious / EntryNextタグを使うと意図した結果が得られるようになりました。プラグインのコードもかなり変えました。

記事を保存した時のこと

再構築ウインドウで再構築した時は良いのですが、ある記事を保存した時、通常はその前後の記事しか再構築されず前後の記事へのリンクがおかしくなってしまいます。(「Movable Typeで記事をファイル出力しない方法を調べてみた」のようにbuild_file_filterを書いたので、リンクやPDFに該当する場合はHTMLが出力されていません。)post_saveで先のロジックを使用して該当の記事を探し、再構築するようにしました。PowerCMS Xと違ってどうすれば再構築できるのか見つけられなかったのですが(Publisherを探そとはしたものの…)、野田さんに教えて頂きました。ありがとうございます。

ここまでの条件に加えてカテゴリを考慮する場合

頑張ればできなくはないと思いますがクエリも増えるししんどそうな気がします…。