WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する

元ネタは WordPress 日本語公式フォーラムの「カスタムフィールドの日付から年別アーカイブリストを作成」です。このような、投稿の日付ではなくてカスタムフィールドに入力した日付でイベントカレンダー的なこととか、そらもう色んなことをひととおりしたい、というご要望は wpxtreme にもたくさん寄せられます。かなりの需要があると思われますので、自力で頑張りたい人のために一例としてやってみます。

仕様

  • カスタムフィールドに入力した日付を元に、年別アーカイブ一覧を出力したり年別アーカイブを表示したりする。
  • カスタムフィールドの値の書式は 'yyyy年mm月dd日'。
  • カスタムフィールドのキーは 英数字。

使い方

wp_get_archives() とほぼ同じですが、パラメータがちょびっと違ってます。

書式
<?php 
my_get_year_archives( array(
	'date_field' => 'mydate',
) );
?>
パラメータ
  • type
    このパラメータはありません。
  • datre_field
    (文字列)日付用のカスタムフィールドのキー。初期値は 'date'。
ちなみに get_archives() は WordPress 2.1 でとっくに deprecated(非推奨)になってるので、wp_get_archives() を使うようにしましょう!

コード

以下をテーマの functions.php にペッとすれば OK◎ タブが激しいですけど、気にしないで。

<?php
function my_get_year_archives( $args = '' ) {
	global $wpdb, $wp_locale;

	$defaults = array(
		'date_field' => 'date',
		'format' => 'html',
		'echo' => true,
		'limit' => '',
		'before' => '',
		'after' => '', 
		'show_post_count' => false,
	);

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

	if ( '' != $limit ) {
		$limit = absint( $limit );
		$limit = ' LIMIT '.$limit;
	}

	$field  = 'm.meta_value';
	$select = "SELECT SUBSTRING($field,1,4) AS `year`, count(p.ID) AS posts";
	$where  = "WHERE p.post_type = 'post' AND p.post_status = 'publish'";
	$where .= $wpdb->prepare( ' AND m.meta_key = %s', $date_field );
	$join   = " INNER JOIN $wpdb->postmeta AS m ON m.post_id = p.ID";
	
	$where  = apply_filters( 'getarchives_where', $where, $r );
	$join   = apply_filters( 'getarchives_join' , $join , $r );

	$output = '';
	$query = "$select FROM $wpdb->posts AS p $join $where GROUP BY SUBSTRING($field,1,4) ORDER BY $field DESC $limit";
	$key = md5( $query );
	$cache = wp_cache_get( 'my_get_year_archives' , 'general' );
	if ( !isset( $cache[ $key ] ) ) {
		$arcresults = $wpdb->get_results( $query );
		$cache[ $key ] = $arcresults;
		wp_cache_set( 'my_get_year_archives', $cache, 'general' );
	} else {
		$arcresults = $cache[ $key ];
	}

	if ( $arcresults ) {
		$afterafter = $after;
		foreach ( (array) $arcresults as $arcresult ) {
			$url = add_query_arg( array( 'meta_key' => $date_field ), get_year_link( $arcresult->year ) );
			$text = sprintf( '%d', $arcresult->year );
			if ($show_post_count)
				$after = '&nbsp;('.$arcresult->posts.')' . $afterafter;
			$output .= get_archives_link( $url, $text, $format, $before, $after );
		}
	}
		
	if ( $echo )
		echo $output;
	else
		return $output;
}

add_action( 'init', 'my_init' );
function my_init() {
	global $wp;
	$wp->add_query_var( 'meta_key' );
}

add_action( 'pre_get_posts', 'my_pre_get_posts' );
function my_pre_get_posts( $query ) {
	if ( $query->is_year ) {
		$meta_query = array(
			array( 
				'key'     => $query->get( 'meta_key' ),
				'value'   => $query->get( 'year'     ),
				'compare' => 'LIKE'
			),
		);
				
		$query->set( 'meta_query' , $meta_query );
		$query->set( 'year'       , ''          );
		$query->set( 'date'       , ''          );
		$query->set( 'meta_key'   , ''          );
	}
} 
?>

ポイント

my_get_year_archives()

  • 指定されたカスタムフィールドの始めの4文字を「年」として、その年に記事が何件あるかを取得します。
  • 年アーカイブのリンクに日付用のカスタムフィールドのキーをクエリ変数としてくっつけます。

my_init()

  • パブリックなクエリ変数に meta_key を追加します。
    これをしとくと URL の後ろに '?meta_key=なんちゃら' の書式でお好みのクエリ変数が使えるようになります。パブリックなクエリ変数には元々どんなものがあるかは wp-includes/class-wp.php の始めの方にある $public_query_vars を見るといいですよ。

my_pre_get_posts()
※WordPress は URL を元にどういう風に記事を取得するか判断します。pre_get_posts アクションではこの「どういう風に」の部分をコッソリ改変することができます。

  • 年別アーカイブなら、meta_key で指定されたカスタムフィールドの値で該当する記事が取得されるように meta_query を仕込みます。

CONCLUSION

フォーラムのご質問の仕様ビッチビチに作ってますので「私のやりたいことと微妙に違うの。」というえびちゃんは、このエントリーを参考に自分で何とかしてみてください。

でも、もしあなたが何日も解決できなくて泣きそうになったり、そんなんハナから自分でやるツモリのないえびちゃんだったりしたときは、wpxtreme までお気軽に お問い合わせ ください。

wpxtreme では、カスタマイズ1案件につき基本 10,500円(税込)にて承っております。数時間後〜どんなに重いカスタマイズでも翌日には納品いたしますよ。これまでたくさんの方々にお喜びいただいております。

さぁ!次はあなたの番です。きっと、圧倒的なスピードとクオリティで異次元のコストパフォーマンスを体験していただけることでしょう。

以上、あからさまな PR でした。

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

13 Comments

  • 【ブログ書いた】WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する http://t.co/0Te4AD5N @wordpress_fan #wordpressjp

  • 【ブログ書いた】WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する http://t.co/0Te4AD5N @wordpress_fan #wordpressjp

  • WordPressカスタムフィールドの日付から年別アーカイブリストを作成

  • RT @kzxtreme: 【ブログ書いた】WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する http://t.co/QG7BPzud @wordpress_fan #wordpressjp

  • 【ブログ書いた】WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する http://t.co/0Te4AD5N @wordpress_fan #wordpressjp

  • イベント日程を整理するのによさそう! RT @kzxtreme WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する http://t.co/aWfkhjyK

  • WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する  |  wpxtreme 仕様 カスタムフィールドに入力した日付を元に、年別アーカイブ一覧を出力したり年別アーカイブを表示したりする。 カスタムフ… http://t.co/QZcBbVhW

  • WordPress でカスタムフィールドの日付から年別アーカイブリストを作成する http://t.co/1Z6pXOdl

  • kura kura

    フォーラムでコメントを頂いたものです。
    とても便利そうなソースで活用させていただければと思うのですが
    私の場合、年月でリストを作りたいのですが、カスタマイズ可能でしょうか。
    お教え頂ければ幸いです。

    • kz kz

      もちろん年月も可能で、類似の納品実績がございます◎
      ががが、現在コードをまとめてお知らせする時間がまったくございません。
      気長にお待ちいただくか、ご発注いただくと確実でございます。

  • カスタムフィールドの日付から年別アーカイブ

  • めちゃくちゃ助かりました、まさにこれ。ありがとうございます…!