カスタムフィールドに入力した日付で月別絞り込み&アーカイブページの整形

カスタムフィールドに入力した日付で月別絞り込み&アーカイブページの整形

イベントやセミナーの開催日などをカスタムフィールドのデイトピッカーで入力し、イベントカレンダー的な用途で使いたい場合があります。
その際、「開催月などでイベントを絞り込みたい」という要望が結構あるんですよね。

投稿日での絞り込みは簡単なのにカスタムフィールドの値でやろうとすると途端に難易度がアップ。
今回はそういった問題を解決する一例を紹介します。

カスタムフィールドの日付で絞り込むためのセレクトボックスを表示

こういう状態を目指します。

まずはfunctions.phpに以下のコードを記述。

//カスタムフィールドの値で月別アーカイブ
function my_get_month_archives( $args = '' ) {
    global $wpdb, $wp_locale;

    $defaults = array(
        'date_field' => '開催日', //カスタムフィールドのフィールド名を記述
        'format' => 'html',
        'echo' => true,
        'limit' => '',
        'before' => '',
        'after' => '', 
        'show_post_count' => true,
    );

    $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`, SUBSTRING($field,6,2) AS `month`, 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), SUBSTRING($field,6,2) ORDER BY $field DESC $limit";
    $key = md5( $query );
    $cache = wp_cache_get( 'my_get_month_archives' , 'general' );
    if ( !isset( $cache[ $key ] ) ) {
        $arcresults = $wpdb->get_results( $query );
        $cache[ $key ] = $arcresults;
        wp_cache_set( 'my_get_month_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_month_link( $arcresult->year, $arcresult->month) );
            $text = sprintf( '%d', $arcresult->year ).'年'.sprintf( '%d', $arcresult->month ).'月';
						$output .= '<option value="'.$url.'">'.$text.'</option>';
        }
    }       
    if ( $echo )
        echo $output;
    else
        return $output;
}

そして、出力するページ(例えばpage-top.phpとか)に以下のコードを記述します。

<select name="archive-dropdown" onChange='document.location.href=this.options[this.selectedIndex].value;'> 
	<option value="">年代から絞り込む</option>
	<?php 
		my_get_month_archives( array(
		'date_field' => '開催日', //カスタムフィールドのフィールド名を記述
		) );
	?>
</select>

これでカスタムフィールドのデートピッカーで入力した日付ベースで月別アーカイブへのリンクがセレクトボックスで表示されます。
ちなみにセレクトボックスで出力されるアーカイブページのリンク先は

hoge.com/date/2018/07/?meta_key=開催日

のようになります。

続いてアーカイブページの設定

アーカイブページの表示を設定していきます。
functions.phpに以下のコードを記述。

//アーカイブページの出力調整
add_action( 'init', 'my_init' );
function my_init() {
    global $wp;
    $wp->add_query_var( 'meta_key' );
}

function change_sort_order( $query ) {
	if ( is_admin() || ! $query->is_main_query() ) {
	return;
	}
	$currnet_date = date_i18n( 'y/m/d' );
	if ( $query->is_month() ) {
    $meta_query = array(
			array( 
				'key'     => $query->get( 'meta_key' ),
				'value'   => $query->get( 'year' ).'.'.sprintf('%02d', $query->get( 'monthnum' )),
				'compare' => 'LIKE'
			),
	);
	$thisyear = get_query_var('year');
	$thismon = get_query_var('monthnum');
	$query->set( 'meta_query', $meta_query );
	$query->set( 'year', '');
	$query->set( 'monthnum','');
	$query->set( 'thisyear',$thisyear);
	$query->set( 'thismon',$thismon);
	$query->set( 'orderby', 'meta_value' );
	$query->set( 'meta_key','開催日');
	$query->set( 'post_type','post');
  } 
}
add_action( 'pre_get_posts', 'change_sort_order' );

続いて出力する側のページ(今回の例だとdate.php)に以下のコードを記述。
ループで回す内容は整理しやすいようパーツ化して読み込みます。

<!-- タイトルの出力 -->
<h1>
	<?php echo get_query_var('thisyear'); ?>年<?php echo get_query_var('thismon'); ?>月の記事一覧
</h1>
<ul>
	<!-- 出力したい内容をループで回す -->
	<?php
	if (have_posts()) : 
		while (have_posts()) :
			the_post();
			//ループの中身はテンプレート化
			get_template_part('include/entry-list');
		endwhile;
	endif;
	?>
</ul>
<?php wp_reset_postdata(); ?>

ループの中身(今回の例だとentry-list.php)を作成。

<li>
	<a href="<?php the_permalink(); ?>">
	<p class="entry-title"><?php the_title(); ?></p>
	<span><?php echo get_post_meta( get_the_ID() , '開催日' ,true); ?></span>
	</a>
</li>

これで最低限の設定はOK。
この時点で出力される内容は以下のようになります。

<!-- タイトルの出力 -->
<h1> 2018年11月の記事一覧 </h1>
<ul>
    <!-- 出力したい内容をループで回す -->
    <li> <a href="http://hoge.com/event/46/">
    <p class="entry-title">タイトルA</p>
    <span>2018.11.22</span> </a> </li>
    <li> <a href="http://hoge.com/event/29/">
    <p class="entry-title">タイトルB</p>
    <span>2018.11.13</span> </a> </li>
</ul>

あとは出力する内容や順番などを調整していけばOK。
比較的小規模な案件の方が向いている出力方法ですがご参考までに。

以下の記事を参考にさせていただきました。

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

【備忘録】WordPress の カスタムフィールドの日付で、日別アーカイブを生成するには

SPONSORED LINK

CONTACT

ご意見やご感想、お仕事のご依頼など
お気軽にご連絡ください。

CONTACT FORM