WordPressで表形式の年月別アーカイブ一覧を作る

年月別アーカイブインデックス
どのブログでも大抵サイドバーにずらーっと月別アーカイブがありますよね。でも、あんなん誰も利用しないと思うんです。あったとしても、あの頃のボクたちを振り返るときくらいですよね。でも、そんなときがまず無いと思うんです。
アーカイブというのは書庫です。wp_get_archives() ごときで出力された安モンのリストだけでは役に立たんのです。そこでちょっとウチのアーカイブページ 見てくれる?見た?そうなの。閲覧者に色んな選択肢を与えてあげるのが配慮ってもんなの。ただ、WordPress のプラグインページみたいに選択肢が多すぎてどれを使ったらいいのかワカランのは本末転倒だから気をつけて。
ちゃんとアーカイブページを見た人はわかると思うけど「DATE」セクションに "2010年 1月 2月" ってリンク達がいましたよね。クールですね。今回はこれを出力してみましょう。せっかくクールなアーカイブページを作っても、そこにまた縦長の月別アーカイブを表示したら台無しですからね。

オリジナルタグを作る

タグとか言うと混乱するよね。ファンクションでええやないの。今回はフィルタなどのフックでは処理できない(元コード内部でフックを呼んでないから)ので、がっつりコードを書きます。ウソです。wp_get_archives() のコードをパクってササッと作りましょう。引数として渡す各種パラメータも同じように利用できるので嬉しいですね。元のコードは wp-includes/general-template.php の 759行目〜です。あっさりできましたので、以下を functions.php に追加してください。

function my_get_archives($args = '') {
  global $wpdb, $wp_locale;

  $defaults = array(
    'limit' => '',
    'format' => 'html', 'before' => '',
    'after' => '', 'show_post_count' => false,
    'echo' => 1,
    'yearorder' => 'DESC',  // 年の並び順
    'monthorder' => 'ASC',  // 月の並び順
  );

  $r = wp_parse_args( $args, $defaults );
  extract( $r, EXTR_SKIP );

  if ( '' != $limit ) {
    $limit = absint($limit);
    $limit = ' LIMIT '.$limit;
  }
  if ( (strtoupper($yearorder) != 'ASC') && (strtoupper($yearorder) != 'DESC') )
    $yearorder = 'DESC';
  if ( (strtoupper($monthorder) != 'ASC') && (strtoupper($monthorder) != 'DESC') )
    $monthorder = 'ASC';

  $where = apply_filters('getarchives_where', "WHERE post_type = 'post' AND post_status = 'publish'", $r );
  $join = apply_filters('getarchives_join', "", $r);

  $output = '';

  $query = "
    SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts 
    FROM $wpdb->posts $join $where 
    GROUP BY YEAR(post_date), MONTH(post_date) 
    ORDER BY YEAR(post_date) $yearorder, MONTH(post_date) $monthorder 
    $limit";
  $key = md5($query);
  $cache = wp_cache_get( 'my_get_archives', 'general' );
  if ( !isset( $cache[ $key ] ) ) {
    $arcresults = $wpdb->get_results($query);
    $cache[ $key ] = $arcresults;
    wp_cache_add( 'my_get_archives', $cache, 'general' );
  } else {
    $arcresults = $cache[ $key ];
  }
  if ( $arcresults ) {
    $afterafter = $after;
    $outputs = $posts = array();
    foreach ( (array) $arcresults as $arcresult ) {
      $url = get_month_link( $arcresult->year, $arcresult->month );
      $text = $wp_locale->get_month($arcresult->month);
      if ( $show_post_count ){
        $after = ' ('.$arcresult->posts.')' . $afterafter;
        $posts[$arcresult->year] += $arcresult->posts;
      }
      $outputs[$arcresult->year] .= get_archives_link($url, $text, $format, $before, $after);
    }
    foreach( $outputs as $year => $output ) {
      $url = get_year_link($year);
      $text = sprintf('%d年', $year);
      if ($show_post_count)
        $after = ' ('.$posts[$year].')' . $afterafter;
      $outputs[$year] 
        = get_archives_link($url, $text, 'custom', '<li>' . $before, $after) 
        . '<ul>' . $outputs[$year] . '</ul></li>';
    }
    $output = implode('', $outputs);
  }
  
  if ( $echo )
    echo $output;
  else
    return $output;
}

お好きな場所で <ul class="my-archive-index"><?php my_get_archives(); ?></ul> とかなんとか書けば、アーカイブ一覧が以下のような ul タグの入れ子になって出力されます。去年はブログの更新をサボッてたみたいですね。

<ul class="my-archive-index">
  <li><a href='http://example.com/2010' title='2010年'>2010年</a>
    <ul>
      <li><a href='http://example.com/2010/01' title='1月'>1月</a></li>
      <li><a href='http://example.com/2010/02' title='2月'>2月</a></li>
    </ul>
  </li>
  <li><a href='http://example.com/2009' title='2009年'>2009年</a>
    <ul>
      <li><a href='http://example.com/2009/01' title='1月'>1月</a></li>
      <li><a href='http://example.com/2009/04' title='4月'>4月</a></li>
      <li><a href='http://example.com/2009/09' title='9月'>9月</a></li>
      <li><a href='http://example.com/2009/11' title='11月'>11月</a></li>
    </ul>
  </li>
</ul>

表形式にレイアウトする

構造さえしっかり出力できれば、ミテクレは css で自由自在です。以下を style.css に追加すると、ウチのアーカイブページみたいな表形式になります。各アーカイブリンクの余白の取り方はお好みで調整してください。こういうところにアナタのセンスが出てしまうので楽しみです。

ul.my-archive-index li {
  overflow:hidden; /* float container */
  padding:.5em 0;
} 
ul.my-archive-index li a{float:left;} /* yearly */
ul.my-archive-index li ul{
  overflow:hidden; /* float container */
  padding-left:1em;
}
ul.my-archive-index li ul li{
  float:left;
  padding:0 0 0 1em;
}

IE では overflow:hidden; なところを zoom:1; とかにするといいかもね。知らんけど。my_get_archives のパラメータには 'yearorder=ASC&monthorder=DESC' てな具合に年/月それぞれの並び順を指定できます。
今回のコードのポイント:

  1. 年をインデックスにした $outputs[] に月別のアーカイブリンクを足し込んでいく。
  2. $outputs[]foreach で年別アーカイブリンクを先頭に足す。
  3. $outputs[]implode で全部くっつけて文字列にする。

プログラミングを初めて3日目くらいのレベルでしたね。

動作確認バージョン
  • WordPress 2.9.1

17 Comments

  • BLOG: WordPressで表形式の年月別アーカイブ一覧を作る http://bit.ly/9bR4HS

  • パクらせて利用させていただきました。ありがとうございます。

  • @na6tiramisu Categories Archive、Monthly Archiveてあったりしますよ。WordPressで表形式の年月別アーカイブ一覧を作る http://bit.ly/amONCL

  • Good Tips!! http://bit.ly/dCxABC

  • Good Tips!!

  • komugi komugi

    とても参考になります。
    カスタム投稿を含めることはできないのでしょうか?

    • kz kz

      $where = apply_filters(‘getarchives_where’, “WHERE post_type = ‘post’ AND post_status = ‘publish’”, $r );

      ってところの

      post_type = ‘post’

      で、含めたいカスタム投稿タイプを追加すれば OK!

      post_type IN (‘post’, ‘my_post_type_1′, ‘my_post_type_2′)

      って感じです◎

  • 年別アーカイブ

  • 年別、月を横並びに表示してコンパクトにする

  • 年別、月を横並びに表示してコンパクトにする

  • WordPressで表形式の年月別アーカイブ一覧を作る  |  wpxtreme http://t.co/ZjZAxAGe

  • WordPressで表形式の年月別アーカイブ一覧を作る  |  wpxtreme http://t.co/ZjZAxAGe

  • アーカイブ一覧を年月入れ子で出力する

  • ◯年×月がずらーっと並ぶ奴じゃなくてちゃんと◯年×月×月って入れ子で出力する

  • カスタム投稿タイプに対応していないので、大元を見ながらこれに修正入れた