MENU

【WordPress×PHP】カスタムフィールドの使い方を解説

【WordPress×PHP】カスタムフィールドの使い方を解説
目次

はじめに

【WordPress×PHP】ショートコードを自作する方法を解説(以下、第13回)では、記事の中に[ ]で書いてPHPの処理を呼び出す方法を解説しました。

今回は、記事ごとに自由な値を保存できるカスタムフィールドと、その値を取り出すget_post_meta()を解説します。「この記事の難易度」「所要時間」のように、記事ごとに違う値を決まった場所・決まった形で表示したいときに役立ちます。

このシリーズの全15回の構成は、第1回の記事の冒頭にまとめています。

カスタムフィールドとは?

記事のタイトルや本文は、データベースのwp_postsというテーブルに保存されています。それとは別に、記事ごとの追加の値を「キー(名前)」と「値」の組で保存しておけるのがカスタムフィールドです。保存先はwp_postmetaというテーブルで、ローカル環境で列を調べるとmeta_id・post_id・meta_key・meta_valueの4つでした。

カスタムフィールドの仕組み。記事ごとの追加の値はwp_postmetaテーブルに記事ID・キー・値の組で保存され、get_post_metaで取り出すと文字列で返る

_edit_lockのように_(アンダースコア)で始まるキーは、WordPressが内部で使う値です。エディターのカスタムフィールド欄には表示されません。

ブロックエディターでカスタムフィールドを入力する

ブロックエディターでは、カスタムフィールドの入力欄は最初は表示されていません。ローカル環境(WordPress 7.1.3)では、次の手順で表示できました。

  1. 編集画面の右上にある「︙」(オプション)をクリックし、いちばん下の「設定」を開く
  2. 「一般」の「高度な設定」にある「カスタムフィールド」をオンにする
  3. 「ページを再読み込みして表示」をクリックする
  4. 編集画面の下にある「メタボックス」をクリックして開く

「カスタムフィールド」の欄で、「名前」にキー、「値」に値を入力し、「カスタムフィールドを追加」をクリックします。2回目以降は、ほかの記事で使ったキーを「— 選択 —」から選べます。新しいキーを入力するときは「新規追加」をクリックします。

ブロックエディターの下部に表示されたカスタムフィールドの欄。名前にkurumico_level・kurumico_target・kurumico_time、値に初級・Excel VBAの基本を学んだ方・15分が入力されている

キーの名前は、第13回のショートコードと同じく、英小文字とアンダースコアでkurumico_のような自分用の接頭辞を付けておくと安心です。

get_post_meta()で値を取り出す

保存した値は、get_post_meta()で取り出します。

$level = get_post_meta( get_the_ID(), 'kurumico_level', true );
echo esc_html( $level );  // 初級
引数内容
1つ目記事のID
2つ目キー
3つ目trueなら値を1つだけ文字列で、false(省略時)なら配列で受け取る

ローカル環境で、いろいろな条件を試しました。

条件結果
第3引数true'初級'(文字列)
第3引数falseまたは省略[ '初級' ](配列)
数値の1200を保存してtrueで取得'1200'(文字列)
存在しないキーをtrueで取得''(空の文字列)
存在しないキーをfalseで取得[](空の配列)
キーを省略その記事のすべてのキーと値が配列で返る

カスタムフィールドは同じキーで複数の値を保存することもできます。その場合の違いが、第3引数の意味です。

第3引数trueとfalseの違い。同じキーに2つの値があるとき、trueは最初の1つを文字列で、falseはすべての値を配列で返す。キーがないときはtrueが空の文字列、falseが空の配列

値が1つだけのカスタムフィールドなら、第3引数はtrueにしておくのが基本です。数値として計算に使うときは、(int) $priceのように型を変えてから使います。

表示するときは、【WordPress×PHP】エスケープとセキュリティの基本(以下、第12回)で解説したesc_html()でエスケープします。カスタムフィールドの値は、記事を書く人が自由に入力できる値だからです。

値を保存・更新・削除する関数

カスタムフィールドは、PHPから書き込むこともできます。

関数働き
add_post_meta( ID, キー, 値 )値を追加する(同じキーがあっても、もう1つ追加される)
update_post_meta( ID, キー, 値 )値を更新する(キーがなければ追加される)
delete_post_meta( ID, キー )そのキーの値を削除する

ローカル環境で試すと、update_post_meta()は、値を変えたときにtrue、同じ値で更新したときにfalseを返しました。また、同じキーに値が2つある状態でupdate_post_meta()を使うと、2つとも同じ値に書き換わりました。4つ目の引数に「書き換え前の値」を指定すると、その値だけが書き換わりました。

自作のフォームから値を保存するような処理を作るときは、第12回で紹介した権限の確認とnonceも必要です。このシリーズでは、値の入力はエディターのカスタムフィールド欄で行い、PHPでは取り出して表示することに絞ります。

SWELLでのカスタムフィールドの使われ方

SWELLでは、編集画面の「SWELL設定」で記事ごとに選べる項目(目次やサイドバーの表示・非表示、サブタイトルなど)が、カスタムフィールドとして保存されています。SWELLのテーマフォルダを調べると、swell_meta_で始まるキーが26種類使われていました。

たとえばlib/overwrite.phpでは、記事ごとの「目次」の設定を、次のように読み込んでいます。

add_action( 'wp', __NAMESPACE__ . '\hook_wp', 11 );
function hook_wp() {
	$the_id = get_queried_object_id();
	// (中略)
	set_show_index( $the_id );
}

function set_show_index( $page_id ) {
	if ( ! is_singular() ) return;

	$meta = get_post_meta( $page_id, 'swell_meta_show_index', true );
	if ( 'show' === $meta ) {
		add_filter( 'swell_is_show_index', '__return_true' );
	} elseif ( 'hide' === $meta ) {
		add_filter( 'swell_is_show_index', '__return_false' );
	}
}

ポイントは次の2つです。

  • get_queried_object_id()で、いま表示しているページのIDを取得している。テンプレートより前に動くwpフックの中など、ループの外でよく使われる関数
  • カスタムフィールドの値によって、【WordPress×PHP】フィルターフックの仕組みと使い方(以下、第10回)で解説したフィルターを付け替えている

なお、ローカル環境でIDに0を指定してget_post_meta()を呼ぶと、空の文字列ではなくfalseが返りました。IDが正しく取れているかにも注意しましょう。

実務サンプル:記事の冒頭に「対象読者・難易度・所要時間」を表示する

技術系のブログでは、記事の冒頭に「対象読者」や「難易度」を載せることがよくあります。これを本文に毎回書く代わりに、カスタムフィールドに入力するだけで、決まった形の表で表示されるようにしてみましょう。

使うキーは、次の3つです。

キー表示名入力例
kurumico_target対象読者Excel VBAの基本を学んだ方
kurumico_level難易度初級
kurumico_time所要時間15分

子テーマのfunctions.phpに、次のコードを追加します。

/**
 * カスタムフィールドに入力した「対象読者・難易度・所要時間」を、本文の前に表で表示する
 */
add_filter( 'the_content', function( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
		return $content;
	}

	$post_id = get_the_ID();
	$items   = [
		'kurumico_target' => '対象読者',
		'kurumico_level'  => '難易度',
		'kurumico_time'   => '所要時間',
	];

	$rows = '';
	foreach ( $items as $key => $label ) {
		$value = get_post_meta( $post_id, $key, true );
		if ( $value === '' ) {
			continue;  // 入力されていない項目は表示しない
		}
		$rows .= '<tr><th>' . esc_html( $label ) . '</th><td>' . esc_html( $value ) . '</td></tr>';
	}

	if ( $rows === '' ) {
		return $content;  // 1つも入力されていなければ、本文だけを返す
	}

	return '<table class="kurumico-info"><tbody>' . $rows . '</tbody></table>' . $content;
} );

子テーマのstyle.cssには、次のCSSを追加します。

.post_content .kurumico-info {
	width: auto;
	margin-bottom: 2em;
	font-size: .95em;
}
.post_content .kurumico-info th {
	width: 7em;
	background: #f0f5fa;
	white-space: nowrap;
}

カスタムフィールドを入力した記事を表示すると、本文の前に表が表示されました。

SWELLの記事ページ。タイトルの下、本文の前に、対象読者・難易度・所要時間の3行の表が表示されている

ローカル環境では、次の動きも確かめています。

  • kurumico_timeだけを削除すると、表は「対象読者」「難易度」の2行になった
  • カスタムフィールドを入力していない記事、トップページの記事一覧、RSSには、表は出なかった
  • 値に<b>タグを入れても、esc_html()によって文字のまま表示された
実務サンプルの処理の流れ。3つのキーをforeachで順番にget_post_metaで取り出し、空なら飛ばし、esc_htmlでエスケープして表の行にする。the_contentフィルターで本文の前に表を付けて返す

コードのポイントは次のとおりです。

  • キーと表示名を配列$itemsにまとめ、foreachで順番に処理している。項目を増やすときは、配列に1行足すだけで済む
  • get_post_meta()の第3引数をtrueにして、値を文字列で受け取っている
  • 未入力のキーは空の文字列''になるので、=== ''で判定して飛ばしている
  • 第10回と同じく、is_singular( 'post' )・in_the_loop()・is_main_query()で、投稿ページの本文だけに絞っている

よくある質問・エラー対処

Q. 「Array」と表示され、警告が出ます

→ get_post_meta()の第3引数を省略していないか確認しましょう。省略すると配列が返るため、そのままechoすると「Array」と表示されます。ローカル環境では、「Warning: Array to string conversion」という警告も出ました。値が1つなら、第3引数にtrueを指定します。


Q. 値を入力したのに、何も表示されません

→ コードのキーとカスタムフィールドの名前が完全に一致しているかを確認しましょう。存在しないキーを指定しても、エラーにはならず空の文字列が返るだけなので、打ち間違いに気付きにくいです。_で始まる名前にした場合も、カスタムフィールド欄に表示されなくなるので注意しましょう。


Q. 数値を保存したのに、計算結果がおかしくなります

→ カスタムフィールドの値は、数値を保存しても文字列で返ってきます。(int)や(float)で型を変えてから計算しましょう。

おわりに(まとめ)

まとめ

カスタムフィールドを使うと、記事ごとの値を本文とは別に保存して、決まった場所・決まった形で表示できます。

  • ✅ カスタムフィールドは、記事ごとに「キー」と「値」の組で保存される
  • ✅ ブロックエディターでは「設定」→「高度な設定」で入力欄を表示する
  • ✅ get_post_meta()の第3引数は、値が1つならtrue
  • ✅ 値は文字列で返り、未入力なら空の文字列になる
  • ✅ 表示するときはesc_html()でエスケープする
  • ✅ 同じキーに複数の値があるとき、update_post_meta()は全部を書き換える

次回はシリーズの総まとめとして、ここまでの知識を使って、子テーマに固定ページ用のテンプレートを作ります。

次回は、子テーマに固定ページ用テンプレートを作る方法について解説予定です。

この記事が、少しでも誰かのお役に立てれば幸いです。

関連記事

当サイトの記事で使用したVBAなどのサンプルをDLできます

この記事のサンプルはありません!

ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


【CSS】テキスト関連プロパティについて基本解説|Webの基礎


よかったらシェアしてね!
  • URLをコピーしました!
目次