古くなった記事にアイコンと注意書きを表示する

記事の編集画面でチェックを入れるだけで、記事一覧のタイトルの左にアイコン、記事のタイトルの下に注意書きを表示する。

サービスが終了している記事や、情報が古くなって明らかに間違っている記事に、内容を修正するまでの間、決まった文言の注意書きを表示できる。チェックした記事は、記事一覧でも確認できる。

注意書きには、チェックした日も表示する。新しい方法の記事への案内など、記事ごとの補足も追加できる。

テーマではなくプラグインにしている。テーマの functions.php に記述すると、テーマを切り替えたときにチェック欄も注意書きも表示されなくなるため。

WordPress 6.0 以上・PHP 7.4 以上。アイコンは Font Awesome を使う。テーマで Font Awesome を読み込んでいない場合は、アイコンだけ表示されない。

PHP

wp-content/plugins/outdated-notice/outdated-notice.php として格納。プラグインの本体。チェックの値の保存、投稿一覧の列と一括操作、記事一覧のアイコン、記事の注意書きをまとめている。長いよ。

<?php
/**
 * Plugin Name: Outdated Notice
 * Description: 記事に注意書きを表示する。編集画面のチェック1つで、一覧のタイトルの左にアイコン、記事のタイトル下に注意書きを表示する。
 * Version:     1.0.0
 * Requires at least: 6.0
 * Requires PHP: 7.4
 * Text Domain: outdated-notice
 *
 * ■ 仕組み
 *   記事ごとに3つの値(投稿メタ)を持つ
 *     _ond_outdated       … 注意書きを表示するか(true / false)
 *     _ond_outdated_date  … チェックした日(Y-m-d)。チェックを入れた日が自動で入る。手で直せる。チェックを外すと空に戻す
 *     _ond_outdated_note  … 補足(任意・手入力)。「新しい方法は〇〇の記事」など。リンク(a)を使える
 *
 * ■ どこで設定するか
 *   ・記事の編集画面の右パネル「注意書き(OUTDATED)」(js/editor.js)
 *   ・投稿一覧の一括操作「注意書きを表示する」「注意書きを外す」(チェックした日は今日になる)
 *   ・投稿一覧に「注意書き」列(印の付いた記事と日付)
 *
 * ■ テーマでの使い方(プラグインを止めてもエラーにならないよう function_exists で囲む)
 *   一覧のタイトルのリンクの直前(タイトルの左):
 *     <?php if ( function_exists( 'ond_icon' ) ) { echo ond_icon(); } ?>
 *   記事ページのタイトル下(日付の行の後ろ):
 *     <?php if ( function_exists( 'ond_notice' ) ) { ond_notice(); } ?>
 *   ※ テーマが ond_notice() を呼んでいないときは、本文の先頭に自動で入れる(the_content)
 *
 * ■ デザイン:css/outdated.css(テーマの CSS で同じクラスを書けば上書きできる)
 *
 * @package Outdated_Notice
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // 直接アクセスされたら何もしない
}

define( 'OND_FILE', __FILE__ );
define( 'OND_DIR', plugin_dir_path( __FILE__ ) );
define( 'OND_URL', plugin_dir_url( __FILE__ ) );
define( 'OND_VERSION', '1.0.0' );

// 投稿メタのキー
define( 'OND_KEY', '_ond_outdated' );
define( 'OND_DATE_KEY', '_ond_outdated_date' );
define( 'OND_NOTE_KEY', '_ond_outdated_note' );

/**
 * 決まった文言(ここを書き換えれば全記事の注意書きが変わる)
 * ・見出し:注意書きの1行目の文字
 * ・本文:補足が空でも必ず表示する文
 */
define( 'OND_LABEL', 'OUTDATED' );
define( 'OND_TEXT', 'この記事の内容は古くなっています。現在は動作しない方法や、存在しないページ・機能が含まれている可能性があります。' );

// アイコン(Font Awesome。テーマで Font Awesome を読み込んでいる場合に表示される)
// ・OND_ICON_CLASS:記事の注意書きの見出し/OND_LIST_ICON_CLASS:一覧のタイトルの左
define( 'OND_ICON_CLASS', 'fa-solid fa-bomb' );
define( 'OND_LIST_ICON_CLASS', 'fa-solid fa-bomb' );


/* ============================================================
 * 1. 投稿メタの登録
 *    show_in_rest でブロックエディタ(REST API)から読み書きできるようにする。
 *    キーが「_」始まり(画面の「カスタムフィールド」に表示されない)なので、auth_callback で編集権限を確認する。
 * ============================================================ */

/**
 * 投稿メタを登録する(init)
 */
function ond_register_meta() {
	// 編集できる人だけ書き込める(その記事を編集する権限があるか)
	$auth = function ( $allowed, $meta_key, $post_id ) {
		return current_user_can( 'edit_post', $post_id );
	};

	register_post_meta(
		'post',
		OND_KEY,
		array(
			'type'              => 'boolean',
			'single'            => true,
			'default'           => false,
			'show_in_rest'      => true,
			'sanitize_callback' => 'rest_sanitize_boolean',
			'auth_callback'     => $auth,
		)
	);

	register_post_meta(
		'post',
		OND_DATE_KEY,
		array(
			'type'              => 'string',
			'single'            => true,
			'default'           => '',
			'show_in_rest'      => true,
			'sanitize_callback' => 'ond_sanitize_date',
			'auth_callback'     => $auth,
		)
	);

	register_post_meta(
		'post',
		OND_NOTE_KEY,
		array(
			'type'              => 'string',
			'single'            => true,
			'default'           => '',
			'show_in_rest'      => true,
			'sanitize_callback' => 'ond_sanitize_note',
			'auth_callback'     => $auth,
		)
	);
}
add_action( 'init', 'ond_register_meta' );

/**
 * 日付のサニタイズ:Y-m-d の形で、実在する日付だけ残す(それ以外は空)
 *
 * @param mixed $value 入力値。
 * @return string Y-m-d または空文字。
 */
function ond_sanitize_date( $value ) {
	$value = sanitize_text_field( (string) $value );
	if ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})$/', $value, $m ) && checkdate( (int) $m[2], (int) $m[3], (int) $m[1] ) ) {
		return $value;
	}
	return '';
}

/**
 * 補足のサニタイズ:リンク・強調・コード・改行だけ許可する
 *
 * @param mixed $value 入力値。
 * @return string 許可したタグだけ残した文字列。
 */
function ond_sanitize_note( $value ) {
	return trim( wp_kses( (string) $value, ond_allowed_note_tags() ) );
}

/**
 * 補足で使えるタグ
 *
 * @return array wp_kses 用の許可リスト。
 */
function ond_allowed_note_tags() {
	return array(
		'a'      => array(
			'href'   => true,
			'target' => true,
			'rel'    => true,
		),
		'strong' => array(),
		'code'   => array(),
		'br'     => array(),
	);
}


/* ============================================================
 * 2. 値の読み出し(テーマ・管理画面の共通)
 * ============================================================ */

/**
 * 注意書きを表示する記事か
 *
 * @param int $post_id 投稿ID。省略時はループ中の投稿。
 * @return bool
 */
function ond_is_outdated( $post_id = 0 ) {
	$post_id = $post_id ? (int) $post_id : (int) get_the_ID();
	if ( ! $post_id ) {
		return false;
	}
	return (bool) get_post_meta( $post_id, OND_KEY, true );
}

/**
 * チェックした日(表示用。記事の DATE と同じ Y-n-j の形)
 *
 * @param int $post_id 投稿ID。
 * @return string 例:2026-11-1。日付が無ければ空文字。
 */
function ond_date_label( $post_id = 0 ) {
	$post_id = $post_id ? (int) $post_id : (int) get_the_ID();
	$date    = (string) get_post_meta( $post_id, OND_DATE_KEY, true );
	if ( '' === $date ) {
		return '';
	}
	$time = strtotime( $date );
	return $time ? wp_date( 'Y-n-j', $time, new DateTimeZone( 'UTC' ) ) : '';
}

/**
 * 今日の日付(サイトのタイムゾーン。Y-m-d)
 *
 * @return string
 */
function ond_today() {
	return wp_date( 'Y-m-d' );
}


/* ============================================================
 * 3. 保存したときの後始末
 *    ・チェックが入っているのに日付が空 → 今日の日付を入れる(一括編集・クイック編集・REST 以外の保存でも抜けないように)
 *    ・チェックが外れている → 日付を空に戻す(補足は消さずに残す。また付けたときに使えるように)
 *    ブロックエディタはメタを REST で別に保存するので、メタの更新のたびに確認する(updated_post_meta / added_post_meta)
 * ============================================================ */

/**
 * チェックの値が変わったら日付をそろえる
 *
 * @param int    $meta_id    メタID(使わない)。
 * @param int    $post_id    投稿ID。
 * @param string $meta_key   メタのキー。
 * @param mixed  $meta_value 保存された値。
 */
function ond_sync_date( $meta_id, $post_id, $meta_key, $meta_value ) {
	if ( OND_KEY !== $meta_key ) {
		return;
	}

	// 無限ループ防止(この中で別のメタを更新するので)
	remove_action( 'updated_post_meta', 'ond_sync_date', 10 );
	remove_action( 'added_post_meta', 'ond_sync_date', 10 );

	$date = (string) get_post_meta( $post_id, OND_DATE_KEY, true );

	if ( rest_sanitize_boolean( $meta_value ) ) {
		if ( '' === $date ) {
			update_post_meta( $post_id, OND_DATE_KEY, ond_today() );
		}
	} elseif ( '' !== $date ) {
		delete_post_meta( $post_id, OND_DATE_KEY );
	}

	add_action( 'updated_post_meta', 'ond_sync_date', 10, 4 );
	add_action( 'added_post_meta', 'ond_sync_date', 10, 4 );
}
add_action( 'updated_post_meta', 'ond_sync_date', 10, 4 );
add_action( 'added_post_meta', 'ond_sync_date', 10, 4 );


/* ============================================================
 * 4. 編集画面(ブロックエディタ)の右パネル
 *    中身は js/editor.js(ビルド不要。wp.element をそのまま使う)
 * ============================================================ */

/**
 * エディタ用の JS を読み込む(enqueue_block_editor_assets)
 */
function ond_editor_assets() {
	$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
	if ( $screen && 'post' !== $screen->post_type ) {
		return; // 投稿(post)の編集画面だけ
	}

	$path = OND_DIR . 'js/editor.js';
	wp_enqueue_script(
		'outdated-notice-editor',
		OND_URL . 'js/editor.js',
		array( 'wp-plugins', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-components', 'wp-data', 'wp-core-data' ),
		file_exists( $path ) ? (string) filemtime( $path ) : OND_VERSION,
		true
	);

	// JS に渡す値(今日の日付・決まった文言)
	wp_add_inline_script(
		'outdated-notice-editor',
		'window.ondSettings = ' . wp_json_encode(
			array(
				'today' => ond_today(),
				'text'  => OND_TEXT,
			)
		) . ';',
		'before'
	);
}
add_action( 'enqueue_block_editor_assets', 'ond_editor_assets' );


/* ============================================================
 * 5. 投稿一覧(管理画面):「注意書き」列と一括操作
 * ============================================================ */

/**
 * 列を追加(タイトルの右)
 *
 * @param array $columns 列の一覧。
 * @return array
 */
function ond_add_column( $columns ) {
	$new = array();
	foreach ( $columns as $key => $label ) {
		$new[ $key ] = $label;
		if ( 'title' === $key ) {
			$new['ond'] = '注意書き';
		}
	}
	if ( ! isset( $new['ond'] ) ) {
		$new['ond'] = '注意書き';
	}
	return $new;
}
add_filter( 'manage_post_posts_columns', 'ond_add_column' );

/**
 * 列の中身(印と日付)
 *
 * @param string $column  列のキー。
 * @param int    $post_id 投稿ID。
 */
function ond_render_column( $column, $post_id ) {
	if ( 'ond' !== $column ) {
		return;
	}
	if ( ! ond_is_outdated( $post_id ) ) {
		echo '<span aria-hidden="true">—</span>';
		return;
	}
	$date = ond_date_label( $post_id );
	printf(
		'<span class="dashicons dashicons-warning" aria-hidden="true"></span><span class="screen-reader-text">%1$s</span> %2$s',
		esc_html__( '注意書きあり', 'outdated-notice' ),
		esc_html( $date )
	);
}
add_action( 'manage_post_posts_custom_column', 'ond_render_column', 10, 2 );

/**
 * 列の幅を狭くする(投稿一覧の画面だけ)
 */
function ond_admin_column_style() {
	$screen = get_current_screen();
	if ( $screen && 'edit-post' === $screen->id ) {
		echo '<style>.fixed .column-ond{width:7em}</style>';
	}
}
add_action( 'admin_head', 'ond_admin_column_style' );

/**
 * 一括操作のメニューに追加
 *
 * @param array $actions 一括操作の一覧。
 * @return array
 */
function ond_bulk_actions( $actions ) {
	$actions['ond_on']  = '注意書きを表示する';
	$actions['ond_off'] = '注意書きを外す';
	return $actions;
}
add_filter( 'bulk_actions-edit-post', 'ond_bulk_actions' );

/**
 * 一括操作の実行
 * ※ ノンス(bulk-posts)は WordPress 本体(edit.php)が、このフィルターを呼ぶ前に確認済み
 *
 * @param string $redirect_to 戻り先の URL。
 * @param string $action      選ばれた操作。
 * @param int[]  $post_ids    選ばれた投稿ID。
 * @return string
 */
function ond_handle_bulk( $redirect_to, $action, $post_ids ) {
	if ( 'ond_on' !== $action && 'ond_off' !== $action ) {
		return $redirect_to;
	}

	$on    = ( 'ond_on' === $action );
	$count = 0;

	foreach ( array_map( 'absint', (array) $post_ids ) as $post_id ) {
		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			continue; // 編集できない記事は飛ばす
		}
		if ( $on ) {
			// すでに注意書きを表示している記事は日付を変えない(最初にチェックした日を残す)
			if ( ! ond_is_outdated( $post_id ) ) {
				delete_post_meta( $post_id, OND_DATE_KEY );
				update_post_meta( $post_id, OND_KEY, true ); // 日付は ond_sync_date で今日になる
			}
		} else {
			delete_post_meta( $post_id, OND_KEY );
			delete_post_meta( $post_id, OND_DATE_KEY );
		}
		++$count;
	}

	return add_query_arg(
		array(
			'ond_done'  => $on ? 'on' : 'off',
			'ond_count' => $count,
		),
		remove_query_arg( array( 'ond_done', 'ond_count' ), $redirect_to )
	);
}
add_filter( 'handle_bulk_actions-edit-post', 'ond_handle_bulk', 10, 3 );

/**
 * 一括操作のあとのお知らせ
 */
function ond_bulk_notice() {
	// 表示するだけ(数とどちらの操作かを表示するだけなので、ノンスは不要)
	// phpcs:disable WordPress.Security.NonceVerification.Recommended
	if ( empty( $_GET['ond_done'] ) ) {
		return;
	}
	$done  = sanitize_key( wp_unslash( $_GET['ond_done'] ) );
	$count = isset( $_GET['ond_count'] ) ? absint( $_GET['ond_count'] ) : 0;
	// phpcs:enable

	$message = ( 'on' === $done )
		? sprintf( '%d件に注意書きを表示しました。', $count )
		: sprintf( '%d件の注意書きを外しました。', $count );

	printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html( $message ) );
}
add_action( 'admin_notices', 'ond_bulk_notice' );


/* ============================================================
 * 6. 公開側:一覧のアイコン・記事の注意書き
 * ============================================================ */

/**
 * 一覧のタイトルの左のアイコン(注意書きを表示しない記事は空文字)
 *
 * @param int $post_id 投稿ID。省略時はループ中の投稿。
 * @return string アイコンのHTML(エスケープ済み)。
 */
function ond_icon( $post_id = 0 ) {
	$post_id = $post_id ? (int) $post_id : (int) get_the_ID();
	if ( ! ond_is_outdated( $post_id ) ) {
		return '';
	}

	$date  = ond_date_label( $post_id );
	$label = $date ? sprintf( '%s %s', OND_LABEL, $date ) : OND_LABEL; // マウスを乗せたときの文字:OUTDATED 2026-11-1

	return sprintf(
		'<span class="outdated-notice-icon" title="%1$s"><i class="%2$s" aria-hidden="true"></i><span class="screen-reader-text">%1$s</span></span>',
		esc_attr( $label ),
		esc_attr( OND_LIST_ICON_CLASS )
	);
}

/**
 * 記事の注意書きの HTML を作る(注意書きを表示しない記事は空文字)
 *
 * @param int $post_id 投稿ID。
 * @return string 注意書きのHTML(エスケープ済み)。
 */
function ond_notice_html( $post_id = 0 ) {
	$post_id = $post_id ? (int) $post_id : (int) get_the_ID();
	if ( ! ond_is_outdated( $post_id ) ) {
		return '';
	}

	$date = ond_date_label( $post_id );
	$note = (string) get_post_meta( $post_id, OND_NOTE_KEY, true );

	$html  = '<aside class="outdated-notice" role="note" aria-label="' . esc_attr( OND_LABEL ) . '">';
	$html .= '<p class="outdated-notice_head">';
	$html .= '<i class="' . esc_attr( OND_ICON_CLASS ) . '" aria-hidden="true"></i> ';
	$html .= '<span class="outdated-notice_label">' . esc_html( OND_LABEL ) . '</span>';
	if ( $date ) {
		$html .= ' <span class="outdated-notice_date">' . esc_html( $date ) . '</span>';
	}
	$html .= '</p>';
	$html .= '<p class="outdated-notice_text">' . esc_html( OND_TEXT ) . '</p>';

	// 補足(手入力したときだけ)。URL だけ書いてもリンクになるよう make_clickable、最後にもう一度 wp_kses
	if ( '' !== trim( $note ) ) {
		$note  = wp_kses( make_clickable( nl2br( $note, false ) ), ond_allowed_note_tags() );
		$html .= '<p class="outdated-notice_note">' . $note . '</p>';
	}

	$html .= '</aside>';

	return $html;
}

/**
 * テーマから呼ぶ:記事のタイトル下に注意書きを表示する(echo する)
 *
 * @param int $post_id 投稿ID。
 */
function ond_notice( $post_id = 0 ) {
	$post_id = $post_id ? (int) $post_id : (int) get_the_ID();
	// テーマで表示したことを記録(本文の先頭に二重に入れないため)
	$GLOBALS['ond_printed'][ $post_id ] = true;
	echo ond_notice_html( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- 関数内でエスケープ済み
}

/**
 * テーマが ond_notice() を呼んでいないときの予備:本文の先頭に入れる(the_content)
 * 記事ページのメインの本文だけが対象(一覧の抜粋・フィード・ウィジェットには入れない)
 *
 * @param string $content 本文。
 * @return string
 */
function ond_prepend_to_content( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
		return $content;
	}
	$post_id = (int) get_the_ID();
	if ( ! empty( $GLOBALS['ond_printed'][ $post_id ] ) ) {
		return $content; // テーマ側で表示済み
	}
	return ond_notice_html( $post_id ) . $content;
}
add_filter( 'the_content', 'ond_prepend_to_content', 5 );

/**
 * 公開側の CSS(注意書き・アイコン)
 * 小さいので全ページで読み込む(一覧はどのページにも表示されるため)
 */
function ond_front_assets() {
	$path = OND_DIR . 'css/outdated.css';
	wp_enqueue_style(
		'outdated-notice',
		OND_URL . 'css/outdated.css',
		array(),
		file_exists( $path ) ? (string) filemtime( $path ) : OND_VERSION
	);
}
add_action( 'wp_enqueue_scripts', 'ond_front_assets' );

チェックを入れて保存したとき、チェックした日が空なら今日の日付を入れる。右パネルを使わず、投稿一覧の一括操作で設定した場合もチェックした日が入るようにする。

記事ごとに保存するもの

  • 注意書きを表示するか(チェックのオン・オフ)
  • チェックした日
  • 補足

保存先は「投稿メタ」。記事ごとにデータを追加して保存できる、WordPress に最初からある仕組み。記事一覧と記事の両方が、同じデータを読んで表示できる。

投稿メタの名前は、先頭を _(アンダースコア)にしている(_ond_outdated など)。先頭が _ でない投稿メタは、編集画面の「カスタムフィールド」に表示され、そこから書き換えや削除ができてしまう。先頭が _ の投稿メタは、テーマに関係なく「カスタムフィールド」に表示されないので、右パネルからしか書き換えられない。

補足に使えるタグは <a> <strong> <code> <br> だけ。それ以外のタグは、保存するときに削除する。

※ outdated-notice フォルダは作成する。フォルダ名は自由。
※ 対象は投稿だけ。固定ページには表示されない。

JavaScript

outdated-notice/js/editor.js として格納。編集画面の右パネル「注意書き(OUTDATED)」を作る。

/**
 * 記事の注意書き(エディタ側):記事の右パネル「注意書き(OUTDATED)」
 *
 * ・チェック「注意書きを表示する」… 入れると今日の日付が自動で入る/外すと日付を空に戻す
 * ・チェックした日 … 手で直せる(文言を見直した日に更新するなど)
 * ・補足 … 任意。「新しい方法は〇〇の記事」など。<a href="…">…</a> が使える。URL だけでもリンクになる
 * ・値は投稿メタ(_ond_outdated / _ond_outdated_date / _ond_outdated_note)として「更新」ボタンで保存される
 * ・ビルド不要(wp.element をそのまま使う)
 */
( function ( wp ) {
	var el = wp.element.createElement;
	var useSelect = wp.data.useSelect;
	var useDispatch = wp.data.useDispatch;
	var CheckboxControl = wp.components.CheckboxControl;
	var TextControl = wp.components.TextControl;
	var TextareaControl = wp.components.TextareaControl;

	// WordPress 6.6 からは wp.editor、それより前は wp.editPost にある
	var PluginDocumentSettingPanel =
		( wp.editor && wp.editor.PluginDocumentSettingPanel ) ||
		( wp.editPost && wp.editPost.PluginDocumentSettingPanel );

	if ( ! PluginDocumentSettingPanel ) {
		return;
	}

	var settings = window.ondSettings || {};

	function OutdatedPanel() {
		// 今の記事の種類とメタを読む
		var data = useSelect( function ( select ) {
			var editor = select( 'core/editor' );
			return {
				postType: editor.getCurrentPostType(),
				meta: editor.getEditedPostAttribute( 'meta' ) || {},
			};
		}, [] );

		var editPost = useDispatch( 'core/editor' ).editPost;

		// 投稿(post)だけに表示する
		if ( 'post' !== data.postType ) {
			return null;
		}

		var meta = data.meta;
		var isOutdated = !! meta._ond_outdated;

		// メタの一部だけ書き換える
		function setMeta( values ) {
			editPost( { meta: Object.assign( {}, meta, values ) } );
		}

		var children = [
			el( CheckboxControl, {
				key: 'check',
				label: '注意書きを表示する',
				help: 'チェックすると、一覧のタイトルの左にアイコン、記事のタイトル下に注意書きが表示されます。',
				checked: isOutdated,
				onChange: function ( checked ) {
					if ( checked ) {
						// 日付が空なら今日を入れる
						setMeta( {
							_ond_outdated: true,
							_ond_outdated_date: meta._ond_outdated_date || settings.today || '',
						} );
					} else {
						// 外したら日付も空に(補足は残す)
						setMeta( { _ond_outdated: false, _ond_outdated_date: '' } );
					}
				},
			} ),
		];

		if ( isOutdated ) {
			children.push(
				el( TextControl, {
					key: 'date',
					label: 'チェックした日',
					type: 'date',
					value: meta._ond_outdated_date || '',
					help: '注意書きの OUTDATED の後ろに表示されます。',
					onChange: function ( value ) {
						setMeta( { _ond_outdated_date: value } );
					},
				} ),
				el( TextareaControl, {
					key: 'note',
					label: '補足(任意)',
					value: meta._ond_outdated_note || '',
					rows: 3,
					help: '決まった文言の下に追加で表示されます。例:新しい方法は <a href="URL">この記事</a>',
					onChange: function ( value ) {
						setMeta( { _ond_outdated_note: value } );
					},
				} ),
				el(
					'p',
					{ key: 'preview', style: { fontSize: '12px', color: '#757575', marginTop: '8px' } },
					'決まった文言:' + ( settings.text || '' )
				)
			);
		}

		return el(
			PluginDocumentSettingPanel,
			{
				name: 'outdated-notice-panel',
				title: '注意書き(OUTDATED)',
				className: 'outdated-notice-panel',
				initialOpen: isOutdated,
			},
			children
		);
	}

	wp.plugins.registerPlugin( 'outdated-notice', {
		render: OutdatedPanel,
		icon: 'warning',
	} );
} )( window.wp );

右パネルで入力した値は、記事の「更新」を押したときに一緒に保存される。

PluginDocumentSettingPanel は、WordPress 6.6 で wp.editPost から wp.editor に移っている。6.6 より前の WordPress でも右パネルが表示されるよう、どちらにあっても使えるようにしている。

※ js フォルダは作成する。
※ 右パネルはブロックエディタだけ。クラシックエディタの場合は、投稿一覧の一括操作で設定する。

CSS

outdated-notice/css/outdated.css として格納。アイコンと注意書きのデザイン。

/**
 * 記事の注意書き(Outdated Notice)
 * テーマの CSS で同じクラスを書けば上書きできる
 */

/* ===== ここから CSS ===== */

/* 一覧:タイトルの左のアイコン */
.outdated-notice-icon {
	margin-right: 0.4em; /* ★ アイコンとタイトルの間 */
	font-size: 80%; /* ★ アイコンの大きさ(タイトルの文字に対して) */
	color: #1d1f28; /* ★ アイコンの色 */
	white-space: nowrap;
	cursor: default;
}

/* 記事:タイトル下の注意書き(文字の大きさ・色は本文と同じ) */
.outdated-notice {
	margin: 12px 0 0; /* ★ 上の余白(日付などとの間) */
	padding: 12px 16px; /* ★ 枠の中の余白 */
	border: 1px dashed #b5b9c6; /* ★ 枠(点線)。dotted にすると細かい点々 */
}
.outdated-notice p {
	margin: 0;
}

/* 1行目:アイコン・OUTDATED・日付 */
.outdated-notice_head {
	font-weight: 500;
}
.outdated-notice_date {
	margin-left: 0.6em;
	font-weight: 300;
}

/* 2行目:決まった文言/3行目:補足(入力したときだけ表示) */
.outdated-notice_text {
	margin-top: 4px;
}
.outdated-notice_note {
	margin-top: 6px;
}

/* 読み上げ用の文字(画面には表示しない。テーマに .screen-reader-text が無い場合のため) */
.outdated-notice-icon .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	border: 0;
	white-space: nowrap;
}

/* ===== ここまで CSS ===== */

注意書きの文字の大きさと色は指定せず、本文と同じにしている。テーマの本文のデザインのまま表示されるため。

※ css フォルダは作成する。

テンプレート

記事一覧と記事のテンプレートに追記。どちらも function_exists() で囲んでいる。プラグインを停止したときに、テーマ側でエラーにならないため。

※テーマによってファイル名・HTML は異なる。the_title() と日付を表示している行を探して追記する。下記の entry-title・entry-meta は説明用の例。

記事一覧 トップ・カテゴリ・タグ・年別・検索結果のテンプレートの、ループの中に追記。<a> の直前に追記する。

変更前

<h2 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>

変更後

<h2 class="entry-title"><?php if ( function_exists( 'ond_icon' ) ) { echo ond_icon(); } // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- 関数内でエスケープ済み ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>

記事 single.php の、日付の行の直後に追記。

変更前

<h1 class="entry-title"><?php the_title(); ?></h1>
<p class="entry-meta"><?php the_time( 'Y-n-j' ); ?></p>

変更後

<h1 class="entry-title"><?php the_title(); ?></h1>
<p class="entry-meta"><?php the_time( 'Y-n-j' ); ?></p>
<?php if ( function_exists( 'ond_notice' ) ) { ond_notice(); } ?>

※ 記事のテンプレートに追記しない場合は、本文の先頭に注意書きが表示される。ブロックテーマで single.php がない場合も同じ。

使い方

  1. 「プラグイン」→「Outdated Notice」の「有効化」
  2. 記事の編集画面 → 右パネルの「投稿」→ 一番下の「注意書き(OUTDATED)」
  3. 「注意書きを表示する」にチェック →「更新」

チェックを入れると、チェックした日に今日の日付が入る。チェックした日はあとから変更できる。チェックを外すと、チェックした日も消える。

補足は、決まった文言の下に表示される。<a href="URL">記事のタイトル</a> のようにリンクを記述できる。URL だけでもリンクになる。

※ 「注意書き(OUTDATED)」は閉じた状態で表示されることがある。見出しを押すと開く。 ※ チェックを外しても、補足は消さずに残す。もう一度チェックを入れたときに、入力し直さなくていいため。

まとめて設定する場合

  1. 「投稿」→「投稿一覧」
  2. 記事にチェック →「一括操作」→「注意書きを表示する」→「適用」

(スクショ:投稿一覧。「一括操作」のメニューと「注意書き」列)

※ すでに注意書きを表示している記事は、チェックした日を変えない。最初にチェックした日を残すため。

変更する場合

変えたいもの変更箇所
注意書きの1行目の文字(OUTDATED)outdated-notice.php の OND_LABEL
決まった文言outdated-notice.php の OND_TEXT
注意書きのアイコンoutdated-notice.php の OND_ICON_CLASS
記事一覧のアイコンoutdated-notice.php の OND_LIST_ICON_CLASS
アイコンの色・大きさ、枠、余白CSS の ★ の行

既存の設定がある場合

日付の行の下に、本文までの余白を指定している場合は、注意書きがその余白の下に表示される。注意書きを日付の行のすぐ下に表示するには、テーマの CSS の最後に下記を追記。注意書きがある記事だけ、余白を注意書きの下に移す。

/* 注意書きがあるときだけ、日付の行の下の余白を注意書きの下に移す */
.entry-meta:has(+ .outdated-notice) {
	margin-bottom: 0;
}
.entry-meta + .outdated-notice {
	margin-bottom: 60px; /* ★ 日付の行の下に指定している余白と同じ値 */
}

※ .entry-meta は、テーマの日付の行の class に変更する。
※ ond_notice() を日付の行の直後に追記している場合に効く。間にほかの要素があると効かない。
※ :has() に対応していないブラウザでは、日付の行と注意書きの間があいたまま表示される。

表示環境によって動きの見え方が異なる場合があるため、本番に反映する前に確認してね。

NOTICES

  • 記事内容は実装させたものがほとんどですが自己責任で参考にしてください。