WordPress のカスタム投稿タイプをブログのように使う場合、月別アーカイブページを表示させたい場合があります。この時のパンくずリストについて、自分でパンくずリストを実装する場合は何とでもなると思いますが、Breadcrumb NavXT などのプラグインを利用している場合はなかなか思うように表示されません。

例えば、カスタム投稿タイプ “blog” の2015年1月のアーカイブページの URL は、http://example.com/blog/date/2015/01/ となりますが、このページのパンくずリストが本来ならば、

Home > ブログ > 2015年 > 1月

と表示させたくても

Home > 2015 > 1月

のように、カスタム投稿タイプのアーカイブページへのリンクが表示されず、さらに2015年のリンク先が、通常の投稿の年別アーカイブページ http://example.com/2015/ になってしまいます。

これは、そもそもカスタム投稿タイプの日付アーカイブは WordPress に標準装備されていない機能らしく、パンくずリストを自分で実装する必要があるようです。

今回このブログの月別アーカブページのパンくずリストを、Breadcrumb NavXT を使ったまま、テンプレートで書き替えてみました。

前提として、パーマリンク設定で通常の投稿には “info” というディレクトリ名を付けてあり、カスタム投稿タイプ “blog” は “with_front: false” を設定して “info” が付かないようにしています。

パンくずリストを書き替えるための考え方は、

  • Home の次にカスタム投稿タイプのアーカイブページへのリンクを追加する
  • 年別アーカイブのリンク先をカスタム投稿タイプの URL に書き替える
  • ついでに、日付の表記が “月” しか表示されないので、”年” と念のため “日” を表示する

の3つです。これらを preg_replace によって書き替えます。

if ( get_post_type() == 'blog' || is_date() ){
  $post_type_link = ' &gt; <a href="'. get_post_type_archive_link($post->post_type). '">'. esc_html(get_post_type_object(get_post_type())->label). '</a>';
  $patterns = array ('/(home.+?<\/a>)/', '/(\/info\/)/', '/(>\d{4})/', '/(\d{1,2})$/');
  $replace = array ('$1'. $post_type_link, '/blog/date/', '$1年', '$1日');
  echo preg_replace($patterns, $replace, bcn_display(true));
}

これを通常の投稿の日付ベースアーカイブでも “年” と “日” を表示させ、他のページのパンくずリストの表示と合わせて書くと以下のようになりました。

<?php if ( function_exists('bcn_display') && !is_front_page() ){
  echo '<div id="topicPath">'. "\n";
  echo '<p><span class="scrText">このページの位置: </span>';
  if ( is_date() ){
    if ( get_post_type() == 'blog' ){
      $post_type_link = ' &gt; <a href="'. get_post_type_archive_link($post->post_type). '">'. esc_html(get_post_type_object(get_post_type())->label). '</a>';
      $patterns = array ('/(home.+?<\/a>)/', '/(\/info\/)/', '/(>\d{4})/', '/(>\d{1,2})$/');
      $replace = array ('$1'. $post_type_link, '/blog/date/', '$1年', '$1日');
    } else {
      $patterns = array ('/(>\d{4})/', '/(>\d{1,2})$/');
      $replace = array ('$1年', '$1日');
    }
    echo preg_replace($patterns, $replace, bcn_display(true));
  } else {
  bcn_display();
}
echo '</p>'. "\n";
echo '</div>';
} ?>

$patterns の中にある /(>\d{4})/ などの “>” は、リンクテキストのみを書き替えるためにその前にあるaタグの “>” を付けています。

パンくずリストの HTML によっては、置換するための正規表現を調整する必要があると思いますが、これで思い通りの表示になりました。

ちなみに、”年” と “日” の表示については、日付ベースアーカイブページのタイトルなどにも同様の方法で表示させています。