カテゴリーやタグにカスタムフィールドを追加する方法

,

投稿や固定ページにカスタムフィールドを追加するのは色々なサイトで紹介されているのですが、タクソノミー(カテゴリー・タグ)やカスタムタクソノミーにカスタムフィールドを追加する方法はどれもカスタムフィールドを簡単に追加する「Advanced Custom Fields」を使った方法がほとんどでした。

個人的にはプラグインを使わないで実装してみたいので、公式ドキュメントなどを見ながら実装してみました。

実装したい機能

まず、実装したいと思っているのが、通常はプラグインで簡単にできるカテゴリーやタグの順番を並び替える機能です。固定ページの順序と同じように数値を入力させて、数値が小さい順にタームを取得して表示できるようにしたいと考えています。

今回は大まかには下記のような機能を実装する必要があります。

カテゴリーやタグを取得して、数値を元に並び替えて出力する部分に関しては別の記事で紹介する予定です。

また、タームの一覧画面で順序の数値を確認できるようにしたり、一覧の並び順そのものを順序通りに並べたいですがその方法は今回は割愛します。

完成したコード

function add_taxonomy_fields($tag) {
	wp_nonce_field(basename(__FILE__), 'term_order_nonce');
	echo '<div class="form-field term-order-wrap">';
	echo '<label for="term-order">順序</label>';
	echo '<input type="text" name="term_order" id="term-order" class="small-text" value="' . $text . '" />';
	echo '<p class="description">数値が小さい順に並び替わります。</p>';
	echo '</div>';
}
add_action('category_add_form_fields', 'add_taxonomy_fields');
add_action('post_tag_add_form_fields', 'add_taxonomy_fields');

function edit_taxonomy_fields($tag) {
	$value = get_term_meta_text($tag->term_id);

	if (!$value) {
		$value = '';
	}

	$value = esc_attr($value);

	echo '<tr class="form-field term-order-wrap">';
	echo '<th><label for="term-order">順序</label></th>';
	wp_nonce_field(basename(__FILE__), 'term_order_nonce');
	echo '<td><input type="number" name="term_order" id="term-order" class="small-text" value="' . $value . '" /><p class="description">数値が小さい順に並び替わります</p></td>';
	echo '</tr>';
}
add_action('category_edit_form_fields', 'edit_taxonomy_fields');
add_action('post_tag_edit_form_fields', 'edit_taxonomy_fields');

function get_term_meta_text($term_id) {
	$value = get_term_meta($term_id, '__term_meta_text', true);
	$value = sanitize_text_field($value);
	return $value;
}

function save_taxonomy_fileds($term_id) {
	if (!isset($_POST['term_order_nonce']) || !wp_verify_nonce($_POST['term_order_nonce'], basename(__FILE__))) {
		return;
	}
	// 既に保存されている値を取得
	$old_value = get_term_meta_text($term_id);

	// 新しい値を取得
	$new_value = isset($_POST['term_order']) ? sanitize_text_field($_POST['term_order']) : '';

	if ($old_value && '' === $new_value) {
		delete_term_meta($term_id, '__term_meta_text');
	} elseif ($old_value !== $new_value) {
		update_term_meta($term_id, '__term_meta_text', $new_value);
	}
}
add_action('create_term', 'save_taxonomy_fileds');
add_action('edited_term', 'save_taxonomy_fileds');

コードの解説

ターム追加時のフォームにフィールドを追加する

まず、add_taxonomy_fieldsという関数を作成します。

function add_taxonomy_fields($tag) {
	wp_nonce_field(basename(__FILE__), 'term_order_nonce');
	echo '<div class="form-field term-order-wrap">';
	echo '<label for="term-order">順序</label>';
	echo '<input type="text" name="term_order" id="term-order" class="small-text" size="25" value="' . $text . '" />';
	echo '<p class="description">数値が小さい順に並び替わります。</p>';
	echo '</div>';
}
add_action('category_add_form_fields', 'add_taxonomy_fields');
add_action('post_tag_add_form_fields', 'add_taxonomy_fields');

関数内の処理は単純です。

2行目は

3〜7行目で入力フィールドのHTMLを出力しています。

9〜10行目{$taxonomy}_add_form_fieldsアクションフックに作った関数を登録します。

このアクションフックはタームを新規追加するフォームが表示されたタイミングで実行されます。

結果的にタクソノミーの新規追加するフォームにフィールドが追加されます。

このフォームにフィールドが追加される

カテゴリーのターム新規追加時とタグのターム新規追加時のフォームにフィールドを追加したいので両方指定しています。

{$taxonomy}の部分をタクソノミー名に置き換えて指定します。

タクソノミーの名前タクソノミー名アクションフック名
カテゴリーcategorycategory_add_form_fields
タグpost_tagpost_tag_add_form_fields
実績(カスタムタクソノミー)portfolioportfolio_add_form_fields
ブログ(カスタムタクソノミー)blogblog_tag_add_form_fields

ターム編集時のフォームにフィールドを追加する

次にedit_taxonomy_fieldsという関数を作成します。前の章と関数の中身は殆ど同じです。

違うところはHTMLを出力する部分と最後のアクションフックが違います。

function edit_taxonomy_fields($tag) {
	$value = get_term_meta_text($tag->term_id);

	if (!$value) {
		$value = '';
	}

	$value = esc_attr($value);

	echo '<tr class="form-field term-order-wrap">';
	echo '<th><label for="term-order">順序</label></th>';
	wp_nonce_field(basename(__FILE__), 'term_order_nonce');
	echo '<td><input type="number" name="term_order" id="term-order" class="small-text" size="25" value="' . $value . '" /><p class="description">数値が小さい順に並び替わります</p></td>';
	echo '</tr>';
}

11〜14行目は前の章とは違い、HTMLがtr要素・th要素・td要素で構成します。

16〜17行目{$taxonomy}_edit_form_fieldsアクションフックに作った関数を登録します。

カテゴリーのターム編集時とタグのターム編集時のフォームにフィールドを追加したいので両方指定しています。

このフォームにフィールドが追加される

{$taxonomy}_edit_form_fieldsアクションフックはタクソノミーの編集するフォームが表示されたタイミングで実行されます。結果的にタクソノミーの編集するフォームにフィールド追加されます。

{$taxonomy}の部分をタクソノミー名に置き換えて指定します。

タクソノミーの名前タクソノミー名アクションフック名
カテゴリーcategorycategory_edit_form_fields
タグpost_tagpost_tag_edit_form_fields
実績(カスタムタクソノミー)portfolioportfolio_edit_form_fields
ブログ(カスタムタクソノミー)blogblog_tag_edit_form_fields

保存した値を取得する関数

保存した値は取得しやすいように別の関数に記述します。

function get_term_meta_text($term_id) {
	$value = get_term_meta($term_id, '__term_meta_text', true);
	$value = sanitize_text_field($value);
	return $value;
}

フィールドに入力した値を保存する

フィールドを作って表示しても値を保存しなければ、意味がありません。

「新規カテゴリーを追加」「更新」をクリックしたときにPOSTメソッドでデータが送信されますので、それをupdate_optionで保存します。

function save_taxonomy_fileds($term_id) {
	if (!isset($_POST['term_order_nonce']) || !wp_verify_nonce($_POST['term_order_nonce'], basename(__FILE__))) {
		return;
	}
	// 既に保存されている値を取得
	$old_value = get_term_meta_text($term_id);

	// 新しい値を取得
	$new_value = isset($_POST['term_order']) ? sanitize_text_field($_POST['term_order']) : '';

	if ($old_value && '' === $new_value) {
		delete_term_meta($term_id, '__term_meta_text');
	} elseif ($old_value !== $new_value) {
		update_term_meta($term_id, '__term_meta_text', $new_value);
	}
}
add_action('create_term', 'save_taxonomy_fileds');
add_action('edited_term', 'save_taxonomy_fileds');

最後に、create_termアクションフック(ターム作成時)とedited_termアクションフック(ターム編集時)に関数を登録します。

作成時と編集時で保存処理を分けることもできますが、今回の場合は特に分ける必要がなかったので同じ処理を呼び出しています。