カスタム投稿タイプで更新した記事も、月別のアーカイブを表示したい時があると思います。

これが簡単なようで意外とハマリました。ちなみに、「『アーカイブページ』内の記事」の表示のことではありません。今回は2通りの方法をご紹介いたします。

function.phpに追記する方法

だいたいこれにぶち当たると思います。

至極簡単で、functions.phpに以下のコードを追記します。

 なにをやっているか?

add_filter(‘getarchives_where’ , ” );

関数リファレンス/add filter – WordPress Codex 日本語版

フィルターは、様々な種類のテキストがデータベースまたはブラウザ画面に送信される前に WordPress が変更を行うフックです。プラグインは、フィルター API を利用して、指定したテキストをその時点で変更する PHP 関数を実行できます。フィルターフックの一覧は プラグイン_API/フィルターフック一覧 を参照してください。

wp_get_archivesなどでアーカイブを取得するために、内部的に日付の検索を行う(という解釈でいいのか…)のですが、このフィルターを利用することで、アーカイブの取得条件を変更できます。

ここで実行される関数my_getarchives_where()は、「$where」と「$r」を受け取っていますが、これはgetarchives_whereをフックするときに渡される変数で、「$r」には、wp_get_archives()が実行されるときのパラメータが展開されたものが入っています。

キーワード省略時の値意味
type‘monthly’アーカイブ種別を指定(’daily’、’weekly’、’monthly’、’yearly’、’postbypost’、’alpha’など)
limit表示件数(正数)
format‘html’表示形式を指定(’html’、’link’、’option’など)
beforeリンク名の前に連結する文字列
afterリンク名の後に連結する文字列
show_post_countfalse投稿件数を表示する場合はtrue、表示しない場合はfalse
echo1表示する場合は1、文字列として取得する場合は0

「$where」には、デフォルトで「WHERE post_type = ‘post’ AND post_status = ‘publish’」が格納されています。これはデータベースの抽出条件ですね。

wp_get_archives:WordPress私的マニュアル

!array_key_exists()

$keyが、その後の引数である$arrayに含まれているかどうかを判断しています。

今回の場合はifの中で直前に「!」がついているので、含まれていない場合に{}内の処理をするわけですが、これはつまり、渡ってきた「$r」のパラメータの中に「post_type」が無ければ、 $whereをデフォルトのまま返して終わるということです。

PHP: array_key_exists – Manual

str_replace( “‘post’”, “‘{$target}’”, $where );

その下で、変数「$target」に、そのpost_typeを代入しています。

直後、str_replace()で$whereの中の’post’を「$target」に置換して「$new_where」に保存して、返しています。

 PHP: str_replace – Manual

add_filter(‘get_archives_link’ , ” );

リンクテキストを返す直前にget_archives_linkフィルターが実行される。$link_htmlには、生成されたリンクテキストの内容が格納されている。

リンクを出力するタイミングで、書き換え用の関数「my_get_archives_link()」を実行します。ここで受け取る値は上記のとおり、生成されたリンクテキスト。つまり「アーカイブリンク」です。

外で定義した$my_archives_post_typeをglobal変数として定義します。
それが空でなければif(){~}内の処理を実行します。

preg_replace( “/\/”, ~ );

$subjectを$replacementで入れ替えるために$patternで検索します。

今回の場合は$link_htmlから、「\」という条件で検索します。
ようするに「」のことなのですが、「[^\”]+」がキモです。これは「『”』以外の文字が1個以上続いている」箇所を表しています。

[^\”]+」に該当した箇所は「」の中の「$1」に挿入されます。

これで置換完了です。直後、$link_htmlを返します。

「wp_get_archive()」でpost_typeを指定する

本来そのような指定の仕方では何の意味もないのですが、上記のようにコードを書くことで「post_type」が機能します。

 テンプレートタグ/wp get archives – WordPress Codex 日本語版

これで、通常はデフォルトの投稿しか出力しない「wp_get_archive」でカスタム投稿タイプを出力できるようになりました!

月ごとのアーカイブへのURLが以下のように出力されます。

…ですが、注意事項として

  • 以降のwp_get_archivesは全て書き換わってしまう
  • 「パーマリンク設定」が「デフォルト」以外だと機能しない。

と、すこし不便です…

「Custom Post Type Permalinks」を使う

「Custom Post Type Permalinks」ダウンロード

これをインストールして有効にすることで、上記のように「post_type」の指定が機能します。
こちらを使ったほうが圧倒的に良い印象です。

[設定]>[パーマリンク設定]から、カスタム投稿ごとに細かいパラメータの付き方も指定できるようになります。

customposttypepermalink

パーマリンク設定で「投稿名」を指定している状態です。

今までと同様に記事単体のページのURLですので、「/%postname%/」を消したURLがアーカイブページとなります。

あとは「archive-投稿タイプ名.php」でテンプレートファイルを作って、おなじみの

で問題ないかと思います。

 

以上、2通りのやり方をご紹介いたしました。

ここは「Custom Post Type Permalinks」に軍配が上がったのではないでしょうか?

 

でわ!

投稿者 satohmsys