概要説明
カテゴリーの編集画面に背景色と文字色の欄を足し、記事のカテゴリーを色つきのボタンで出すコード。前のコードは PHP 8 の警告、色の欄の値がそのまま HTML に入る、クイック編集で色が消える問題があったので、タームメタと nonce、色のチェックで書き直し、作業環境で確かめました。
~ 目次 ~
カテゴリーごとに色を変えたいときに
管理画面のカテゴリーの画面で色を決められるようにすると、カテゴリーを足したときも、CSS を書き足さずに色を付けられます。
この記事のコードでは、色はカテゴリーごとの「タームメタ」に保存します。色のコード(#ff0000 など)でない値は保存しません。
カテゴリーの画面に、背景色・文字色の欄を足す
/*----------------------------------------------------
カテゴリーに背景色・文字色を持たせる(タームメタ)
----------------------------------------------------*/
// 1. 保存する値の決まり(色のコードだけを受け付ける)
function fs_cat_color_register_meta() {
foreach ( array( 'cat_color_bg', 'cat_color_txt' ) as $key ) {
register_term_meta( 'category', $key, array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_hex_color',
'show_in_rest' => true,
) );
}
}
add_action( 'init', 'fs_cat_color_register_meta' );
// 2. 入力欄(新規追加の画面)
function fs_cat_color_add_fields() {
wp_nonce_field( 'fs_cat_color_save', 'fs_cat_color_nonce' );
?>
<div class="form-field">
<label for="cat_color_bg">カテゴリー背景色</label>
<input type="text" name="cat_color_bg" id="cat_color_bg" value="" class="fs-color-field" placeholder="#1e73be">
</div>
<div class="form-field">
<label for="cat_color_txt">カテゴリー文字色</label>
<input type="text" name="cat_color_txt" id="cat_color_txt" value="" class="fs-color-field" placeholder="#ffffff">
</div>
<?php
}
add_action( 'category_add_form_fields', 'fs_cat_color_add_fields' );
// 3. 入力欄(編集の画面)
function fs_cat_color_edit_fields( $term ) {
$colors = fs_get_category_colors( $term->term_id );
wp_nonce_field( 'fs_cat_color_save', 'fs_cat_color_nonce' );
?>
<tr class="form-field">
<th scope="row"><label for="cat_color_bg">カテゴリー背景色</label></th>
<td><input type="text" name="cat_color_bg" id="cat_color_bg" value="<?php echo esc_attr( $colors['bg'] ); ?>" class="fs-color-field"></td>
</tr>
<tr class="form-field">
<th scope="row"><label for="cat_color_txt">カテゴリー文字色</label></th>
<td><input type="text" name="cat_color_txt" id="cat_color_txt" value="<?php echo esc_attr( $colors['txt'] ); ?>" class="fs-color-field"></td>
</tr>
<?php
}
add_action( 'category_edit_form_fields', 'fs_cat_color_edit_fields' );
// 4. 保存(自分の入力欄が送られたときだけ)
function fs_cat_color_save( $term_id ) {
if ( ! isset( $_POST['fs_cat_color_nonce'] )
|| ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['fs_cat_color_nonce'] ) ), 'fs_cat_color_save' ) ) {
return; // クイック編集や、ほかの処理から呼ばれたときは何もしない
}
if ( ! current_user_can( 'edit_term', $term_id ) ) {
return;
}
foreach ( array( 'cat_color_bg', 'cat_color_txt' ) as $key ) {
$color = isset( $_POST[ $key ] ) ? sanitize_hex_color( wp_unslash( $_POST[ $key ] ) ) : '';
update_term_meta( $term_id, $key, (string) $color ); // 色でない値は空になる
}
}
add_action( 'created_category', 'fs_cat_color_save' );
add_action( 'edited_category', 'fs_cat_color_save' );
// 5. 管理画面でカラーピッカーを使う
function fs_cat_color_admin_scripts( $hook ) {
if ( ! in_array( $hook, array( 'edit-tags.php', 'term.php' ), true ) ) {
return;
}
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'wp-color-picker' );
wp_add_inline_script( 'wp-color-picker', 'jQuery(function($){ $(".fs-color-field").wpColorPicker(); });' );
}
add_action( 'admin_enqueue_scripts', 'fs_cat_color_admin_scripts' );
// 6. 色を取り出す(前の書き方で保存した cat_{id} のオプションも読む)
function fs_get_category_colors( $term_id ) {
if ( metadata_exists( 'term', $term_id, 'cat_color_bg' ) ) {
$bg = get_term_meta( $term_id, 'cat_color_bg', true );
$txt = get_term_meta( $term_id, 'cat_color_txt', true );
} else {
$old = get_option( 'cat_' . $term_id ); // 一度も保存し直していないカテゴリー
$bg = is_array( $old ) ? ( $old['cat_color_bg'] ?? '' ) : '';
$txt = is_array( $old ) ? ( $old['cat_color_txt'] ?? '' ) : '';
}
return array(
'bg' => (string) sanitize_hex_color( $bg ),
'txt' => (string) sanitize_hex_color( $txt ),
);
}
// 7. 色つきのカテゴリーボタンの HTML を返す
function fs_get_category_color_buttons( $post_id = null ) {
$html = '';
foreach ( get_the_category( $post_id ) as $cat ) {
$colors = fs_get_category_colors( $cat->term_id );
$style = '';
if ( $colors['bg'] ) {
$style .= 'background-color:' . $colors['bg'] . ';';
}
if ( $colors['txt'] ) {
$style .= 'color:' . $colors['txt'] . ';';
}
$html .= sprintf(
'<a class="cat_btn" href="%s" rel="category tag"%s>%s</a>',
esc_url( get_category_link( $cat ) ),
$style ? ' style="' . esc_attr( $style ) . '"' : '',
esc_html( $cat->name )
);
}
return $html;
}
// テンプレートでそのまま出すとき
function fs_the_category_color_buttons( $post_id = null ) {
echo fs_get_category_color_buttons( $post_id ); // 中身は上でエスケープ済み
}
| 書き方 | 役目 |
|---|---|
register_term_meta( 'category', … ) |
カテゴリーのタームメタ cat_color_bg・cat_color_txt を登録。sanitize_hex_color で、色のコードだけを受け付ける |
| category_add_form_fields | カテゴリーの新規追加の画面に欄を出す |
| category_edit_form_fields | カテゴリーの編集の画面に欄を出す。値は esc_attr で出す |
| wp_nonce_field と wp_verify_nonce | この欄から送られたときだけ保存する。クイック編集など、ほかの保存では何もしない |
current_user_can( 'edit_term', … ) |
そのカテゴリーを直せる人だけが保存できる |
| created_category・edited_category | カテゴリーを足したとき・直したときだけ動く(タグなど、ほかの分類では動かない) |
| wp-color-picker | WordPress に入っているカラーピッカーで色を選べるようにする(カテゴリーの画面だけで読み込む) |
| fs_get_category_colors() | 色を取り出す。タームメタがまだないカテゴリーは、前のコードで保存した cat_{ID} のオプションから読む |
| fs_get_category_color_buttons() | ボタンの HTML を返す。リンクは get_category_link で作り、名前は esc_html、style は esc_attr で出す |
上のコードを足すと、下のようにカテゴリーの画面に欄が増えます(画像は前のコードの入力欄です。新しいコードでは、欄をクリックするとカラーピッカーが開きます)。
ボタンの見た目(CSS)
.cat_btn {
display: inline-block;
padding: 5px 10px;
margin: 0 10px 10px 0;
border-radius: 5px;
background-color: #666; /* 色を決めていないカテゴリー */
color: #fff;
text-decoration: none;
}
style.css には <style> のタグを書きません(前の記事のコードには書いてあり、CSS のファイルに入れると、すぐ後ろの .cat_btn の指定がまるごと効かなくなります)。色を決めていないカテゴリーは、ここの色になります。
色つきのカテゴリーボタンを出す
<?php fs_the_category_color_buttons(); ?>
文字列につないで使うときは、HTML を返す fs_get_category_color_buttons() を使います。
echo '<p class="date">' . fs_get_category_color_buttons( get_the_ID() ) . '</p>';
前のコードの the_category_color_btn() は、その場で echo する関数でした。上のように文字列につなぐと、ボタンが <p> の外(前)に出てしまいます。
前の書き方との違い
| 比べること | 前の書き方 | 新しい書き方 |
|---|---|---|
| 保存する場所 | カテゴリーごとにオプション cat_{ID} を作る(自動で読み込まれ、カテゴリーを消しても残る) | タームメタ(カテゴリーを消すと一緒に消える) |
| 色を保存していないカテゴリーの編集画面 | PHP 8 で「Trying to access array offset on false」の Warning | 警告なし |
| 色の欄に色でない値 | そのまま保存し、style にそのまま出す(ほかの属性を入れられる) | sanitize_hex_color で空にする |
| クイック編集で名前を直す | 色が空になる | 色はそのまま |
| 動く場所 | create_term・edited_term(タグなどすべての分類) | カテゴリーだけ |
| リンク | /archives/category/ を手で書く | get_category_link(パーマリンクの設定に合わせる) |
確かめた結果
このサイトの作業環境(WordPress 7.1.3・PHP 8.3)で、試しのカテゴリーを作り、前のコードと新しいコードを比べました(確かめたあと、カテゴリーと作られたデータは消しました)。
| 試したこと | 前のコード | 新しいコード |
|---|---|---|
| 色を保存していないカテゴリーの編集画面 | Warning が 2 つ | 警告なし |
背景色に red;" onmouseover="alert(1) を保存 |
そのまま保存され、ボタンに onmouseover の属性が入った | 空になった(#FF0000 はそのまま保存) |
| 色の欄なしで保存(クイック編集と同じ) | 背景色・文字色が空になった | #1e73be・#fff のまま |
| nonce がちがう・権限のない人 | (確かめなし) | 保存しなかった |
| 名前に & を含むカテゴリー | (確かめなし) | & にエスケープして出た |
| 色を空にして保存 | (確かめなし) | style のないボタンになった |
| カテゴリーを消す | オプション cat_{ID} が残った | タームメタも消えた |
| 前のコードで色を保存したカテゴリー | ― | 前の色(例:#ae6d4c・#ffffff)を読めた |
| カテゴリーの画面での読み込み | ― | カラーピッカーを読み込み、ほかの画面では読み込まない |
前のコードから入れ替えるとき
前のコードは消してから、新しいコードを入れます。両方を残すと、前のコードの保存もいっしょに動いてしまいます。
前のコードで決めた色は、新しいコードでもそのまま表示されます。カテゴリーの編集画面で一度保存すると、色がタームメタに移ります。テンプレートの the_category_color_btn( $post->ID ) は fs_the_category_color_buttons( $post->ID ) に書き換えます。


