[WordPress General] wp get archives にないカテゴリ毎の月次アーカイブに対応する

カテゴリ毎の月次アーカイブを呼び出す関数がないようで悩みました。

Contents

wp_get_archives

wp get archives にはカテゴリを指定するオプションがありませんでした。

wp_get_cat_archives

ググってみると Archives for a category で解決されている方が多かったのですが、サイトを見ると Warning と書いてあり、2009年からメンテしていないとのこと。公式からもダウンロードできないです。
フックとか WordPress の深いところを全く知らないので、困っていたところ、こちらの記事を見つけました。
ありがとうございます。

前段の add_filter は理解できていないのですが、後段(echo flag 以外)は理解できたので、必要だったオプションタグの出力に対応させてみました。

functions.php
add_filter('getarchives_where', 'custom_archives_where', 10, 2);
add_filter('getarchives_join', 'custom_archives_join', 10, 2);
function custom_archives_join($x, $r) {
  global $wpdb;
  $cat_ID = $r['cat'];
  if (isset($cat_ID)) {
    return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
  } else {
    return $x;
  }
}
function custom_archives_where($x, $r) {
  global $wpdb;
  $cat_ID = $r['cat'];
  if (isset($cat_ID)) {
    return $x . " AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id IN ($cat_ID)";
  } else {
    $x;
  }
}
function wp_get_cat_archives($opts, $cat) {
  $args = wp_parse_args($opts, array('echo' => '1')); // default echo is 1.
  $echo = $args['echo'] != '0'; // remember the original echo flag.
  $args['echo'] = 0;
  $args['cat'] = $cat;
  $tag = ($args['format'] === 'option') ? 'option' : 'li';
  $archives = wp_get_archives(build_query($args));
  $archs = explode('</'.$tag.'>', $archives);
  $links = array();
  foreach ($archs as $archive) {
    $link = preg_replace("/='([^']+)'/", "='$1?cat={$cat}'", $archive);
    array_push($links, $link);
  }
  $result = implode('</'.$tag.'>', $links);
  if ($echo) {
    echo $result;
  } else {
    return $result;
  }
}

ビュー側でこんな指定をします。

index.php
<select>
  <?php wp_get_cat_archives('type=monthly&format=option&show_post_count=1', 2); ?>
</select>

追記

アクセスが多いので追記(2017/12/04)。
こちらのサイトも合わせて読んでください。

補遺

以下、アクションフックやフィルタフックの勉強をするときに見直す。
Railsでもお世話なった方。プラグイン形式にされている。

functions.php あたりで対応しているもの。

フック