はじめに
【WordPress×PHP】ショートコードを自作する方法を解説(以下、第13回)では、記事の中に[ ]で書いてPHPの処理を呼び出す方法を解説しました。
今回は、記事ごとに自由な値を保存できるカスタムフィールドと、その値を取り出すget_post_meta()を解説します。「この記事の難易度」「所要時間」のように、記事ごとに違う値を決まった場所・決まった形で表示したいときに役立ちます。
このシリーズの全15回の構成は、第1回の記事の冒頭にまとめています。
カスタムフィールドとは?
記事のタイトルや本文は、データベースのwp_postsというテーブルに保存されています。それとは別に、記事ごとの追加の値を「キー(名前)」と「値」の組で保存しておけるのがカスタムフィールドです。保存先はwp_postmetaというテーブルで、ローカル環境で列を調べるとmeta_id・post_id・meta_key・meta_valueの4つでした。

_edit_lockのように_(アンダースコア)で始まるキーは、WordPressが内部で使う値です。エディターのカスタムフィールド欄には表示されません。
ブロックエディターでカスタムフィールドを入力する
ブロックエディターでは、カスタムフィールドの入力欄は最初は表示されていません。ローカル環境(WordPress 7.1.3)では、次の手順で表示できました。
- 編集画面の右上にある「︙」(オプション)をクリックし、いちばん下の「設定」を開く
- 「一般」の「高度な設定」にある「カスタムフィールド」をオンにする
- 「ページを再読み込みして表示」をクリックする
- 編集画面の下にある「メタボックス」をクリックして開く
「カスタムフィールド」の欄で、「名前」にキー、「値」に値を入力し、「カスタムフィールドを追加」をクリックします。2回目以降は、ほかの記事で使ったキーを「— 選択 —」から選べます。新しいキーを入力するときは「新規追加」をクリックします。

キーの名前は、第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引数の意味です。

値が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;
}カスタムフィールドを入力した記事を表示すると、本文の前に表が表示されました。

ローカル環境では、次の動きも確かめています。
kurumico_timeだけを削除すると、表は「対象読者」「難易度」の2行になった- カスタムフィールドを入力していない記事、トップページの記事一覧、RSSには、表は出なかった
- 値に
<b>タグを入れても、esc_html()によって文字のまま表示された

コードのポイントは次のとおりです。
- キーと表示名を配列
$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()は全部を書き換える
次回はシリーズの総まとめとして、ここまでの知識を使って、子テーマに固定ページ用のテンプレートを作ります。
次回は、子テーマに固定ページ用テンプレートを作る方法について解説予定です。
この記事が、少しでも誰かのお役に立てれば幸いです。
関連記事
※1回買えば複数サイトで使い回しOK
当サイトの記事で使用したVBAなどのサンプルをDLできます
この記事のサンプルはありません!
ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


