WordPress には先頭固定表示という機能があります。特定の記事を投稿一覧の先頭に固定表示する機能で、重要なお知らせ等を目立たせることができます。

便利な機能ですが、これを指定した日付で自動で解除するというような表示期限を設定する機能はありません。PublishPress Future というプラグインを使用すればこれを実現できますが、このプラグインは非公開や削除、カテゴリー変更といった投稿の様々なステータス変更をスケジューリングするもので機能が多く、今回は先頭固定表示に期限を設定したいだけなので、このプラグインは使用せず、ChatGPT とやりとりしながら、カスタムフィールドと PHP で実現することにしました。

まず、カスタムフィールドの日付フィールドで先頭固定表示期限を作成します。カスタムフィールドは Advanced Custom Fields (ACF®) を使い、フィールド名を sticky_until、戻り値の形式を Ymd とします。

このカスタムフィールドで設定した期限を過ぎたら、自動で先頭固定表示を解除する処理を functions.php に追記します。

add_action('init', function () {
	$today = current_time('Ymd');
	$args = [
		'post_type'      => 'post',
		'posts_per_page' => -1,
		'post__in'       => get_option('sticky_posts'),
		'meta_query'     => [
			[
				'key'     => 'sticky_until',
				'value'   => $today,
				'compare' => '<',
				'type'    => 'NUMERIC',
			]
		]
	];
	$expired = get_posts($args);

	if ($expired) {
		$sticky = get_option('sticky_posts');
		foreach ($expired as $post) {
			$sticky = array_diff($sticky, [$post->ID]);
		}
		update_option('sticky_posts', $sticky);
	}
});

アクセス時に、カスタムフィールド sticky_until の値が今日より小さい(過去の日付)投稿を検索し、該当の投稿があれば、先頭固定表示を解除し、合わせて sticky_until の値を削除します。

これで自動解除の機能は実現できたのですが、このままでは先頭固定表示を設定していない投稿の編集画面にも表示期限のカスタムフィールドが表示されますので、先頭固定表示を設定したときのみカスタムフィールドを表示するようにします。ACF のロケーションルールの条件に先頭固定表示があればよいのですが、残念ながらないので、JavaScript で表示/非表示を切り替えることにします。

(テーマディレクトリ)/js/sticky-until.js で先頭固定表示 ON の時だけカスタムフィールドを表示するようにします。

(function (wp, $) {
  if (!wp || !wp.data) return;
	
  const select = wp.data.select('core/editor');
	
  function togglePostbox() {
		const isSticky = select.getEditedPostAttribute('sticky');
		
		$('.acf-field[data-name="sticky_until"]').each(function () {
			const $postbox = $(this).closest('.acf-postbox');
				
			if (isSticky) {
				$postbox.show();
			} else {
				$postbox.hide();
			}
		});
	}
	
	// 初期表示
	togglePostbox();
	
	// 変更監視
	wp.data.subscribe(togglePostbox);
	
})(window.wp, jQuery);

これを投稿画面および編集画面で読み込む処理を functions.php に追記します。

add_action('admin_enqueue_scripts', function ($hook) {
	if ($hook !== 'post.php' && $hook !== 'post-new.php') {
		return;
	}
	
	wp_enqueue_script('sticky-until-control', get_template_directory_uri(). '/js/sticky-until.js', array('jquery'), false, true);
});

これで先頭固定表示にチェックを入れると期限日設定のカスタムフィールドが表示され、設定した期限日が過ぎると自動で先頭固定表示が解除されます。