シリーズ『WordPressでイベント投稿を作る』~

日付形式のカスタムフィールドを元にどのようなアーカイブページを作るか

日付形式のカスタムフィールドを元にどのようなアーカイブページを作るか



WordPressでイベント投稿を作成する際に、カスタムフィールドで「開催日」などの日付を入力するように設計することになると思いますが、さて、「投稿日」ではなく、「開催日」をベースに投稿をアーカイブ(「2019年1月のイベント」等)として表示するにはどうするかを悩みました。

一つ目の方法は、そもそもの投稿日を起点としているクエリを改変して、カスタムフィールドの「開催日」に入れ替えるという方法。

それには以下の記事が参考になりそうです。

Archive Listings Filtered by Date Values in a Custom Field/Post Meta?
参考
Archive Listings Filtered by Date Values in a Custom Field/Post Meta?

カスタムフィールド/投稿メタの日付値で絞り込まれたアーカイブリスト

Archive Listings Filtered by Date Values in a Custom Field/Post Meta? WordPress Development Stack Exchange

ただ、クエリの改変はその後の仕様変更に対するリスクも高まるのと、基本的にイベントの開催日は現時点よりも未来の日付になるので、本来は予約投稿となるのが正しく解釈出来るかテストをしなくてはならないのが面倒に。

また、常時「開催日」順に投稿クエリが並び替えられることになるので、「最近追加したイベント」という投稿リストも使えなくなる可能性があります。

そこで、まぁ、色々と考えた結果、イベントの保存時に開催日を元にカスタムタクソノミー「イベントアーカイブ」に

  • 2019年1月のイベント
  • 2019年2月のイベント
  • 2019年3月のイベント
  • 2019年4月のイベント

のようなタームを追加する、という方法です。

これでタームのリンクがそのままアーカイブページになるので、煩わしいコードも書かなくても良いはず。

まずはカスタム投稿(event)とカスタムタクソノミー(event_archive)の登録

$event_labels  = array(
	'name'               => 'イベント',
	'singular_name'      => 'イベント',
	'menu_name'          => 'イベント',
	'name_admin_bar'     => 'イベント',
	'add_new'            => '新規追加',
	'add_new_item'       => '新規イベントを追加',
	'new_item'           => '新規イベント',
	'edit_item'          => 'イベントの編集',
	'view_item'          => 'イベントの表示',
	'all_items'          => 'すべてのイベント',
	'search_items'       => 'イベントの検索',
	'not_found'          => 'イベントが見つかりませんでした。',
	'not_found_in_trash' => 'ゴミ箱にイベントが見つかりませんでした。',
);
$event_support = array(
	'title',
	'revisions',
	'thumbnail',
	'editor',
	'excerpt',
	'comments',
);
register_post_type(
	'event',
	array(
		'labels'              => $event_labels,
		'public'              => true,
		'hierarchical'        => false,
		'has_archive'         => true,
		'menu_icon'           => 'dashicons-calendar-alt',
		'exclude_from_search' => false,
		'show_ui'             => true,
		'show_in_menu'        => true,
		'show_in_rest'        => true,
		'rest_base'           => 'event',
		'menu_position'       => 6,
		'rewrite'             => array( 'slug' => 'event' ),
		'supports'            => $event_support,
	)
);
$event_archive_labels = array(
	'name'                       => 'イベントアーカイブ',
	'singular_name'              => 'イベントアーカイブ',
	'search_items'               => 'イベントアーカイブを検索',
	'popular_items'              => '人気のイベントアーカイブ',
	'all_items'                  => 'すべてのイベントアーカイブ',
	'edit_item'                  => 'イベントアーカイブの編集',
	'update_item'                => 'イベントアーカイブの更新',
	'add_new_item'               => '新規イベントアーカイブを追加',
	'new_item_name'              => '新規イベントアーカイブ名',
	'separate_items_with_commas' => 'イベントアーカイブが複数ある場合はコンマで区切ってください',
	'add_or_remove_items'        => 'イベントアーカイブの追加もしくは削除',
	'choose_from_most_used'      => 'よく使われているイベントアーカイブから選択',
	'menu_name'                  => 'イベントアーカイブ',
);
register_taxonomy(
	'event_archive',
	'event',
	array(
		'labels'                => $event_archive_labels,
		'hierarchical'          => false,
		'show_ui'               => true,
		'show_admin_column'     => true,
		'show_in_rest'          => true,
		'rest_base'             => 'event_archive',
		'update_count_callback' => '_update_post_term_count',
		'query_var'             => true,
		'rewrite'               => array(
			'slug' => 'event_archive',
		),
	)
);

次に保存時のフックを

function presave_option() {
	global $post;
	if ( 'event' === $post->post_type ) {
		$from_date    = get_post_meta( $post->ID, 'from_date', true );
		$archive_name = date( 'Y年n月', strtotime( $from_date ) ) . 'のイベント';
		$archive_slug = date( 'Y-n', strtotime( $from_date ) );
		if ( ! term_exists( $archive_slug, 'event_archive' ) ) {
			wp_insert_term( $archive_name, 'event_archive', $args = array( 'slug' => $archive_slug ) );
		}
		wp_delete_object_term_relationships( $post->ID, 'event_archive' );
		wp_set_object_terms( $post->ID, array( $archive_slug ), 'event_archive', true );
	}
}
add_action( 'save_post', 'presave_option', 999 );

詳しく説明すると、

$from_date = get_post_meta( $post->ID, 'from_date', true );

で開催日のカスタムフィールド「from_date」を取得
 

$archive_name = date( 'Y年n月', strtotime( $from_date ) ) . 'のイベント';
$archive_slug = date( 'Y-n', strtotime( $from_date ) );

で登録するイベントアーカイブのターム名、スラグを作成
 

if ( ! term_exists( $archive_slug, 'event_archive' ) ) {
	wp_insert_term( $archive_name, 'event_archive', $args = array( 'slug' => $archive_slug ) );
}

で、未登録のタームだったら新規にイベントアーカイブのタームを作成
 

wp_delete_object_term_relationships( $post->ID, 'event_archive' );

で、一旦イベント投稿に関連付けられているイベントアーカイブタームをすべて解除(開催日が変更になった場合の為)
 

wp_set_object_terms( $post->ID, array( $archive_slug ), 'event_archive', true );

で、イベント投稿にイベントタームを追加

となります。

書きながら気づきましたが、イベント終了日が次の月になった場合はイベントアーカイブのタームをさらに追加する必要があるな、と。これに対応すればむしろ最初に案より管理が便利になります。

もう少し改良してみよう。

今日はここまで

関連する記事



シリーズ『WordPressでイベント投稿を作る』


日付形式のアーカイブページを階層タクソノミーに変更
日付形式のアーカイブページを階層タクソノミーに変更

日付形式のカスタムフィールドを元にどのようなアーカイブページを作るか の改変。 どうせなら、イベントアーカイブも「年」「月」で階層アーカイブにした方が管理しやすいと思い直しまして、以下のように修正です。 register…


こちらはいかが?


1 件のコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*(必須)

*(必須・表示されません)