制作実績へ「担当範囲」のような決まった情報を追加する場合は、投稿メタへ保存できます。このレッスンではACFを使わず、WordPress標準APIで入力欄から表示までを実装します。
管理画面に入力欄を出すだけでは安全に保存できません。送信元、権限、自動保存、入力値を確認してからデータベースへ保存します。
メタボックスを登録する
カスタムフィールドは入力欄を追加するだけでなく、安全を確認して保存する処理まで必要です。

function wpload_add_works_meta_box() {
add_meta_box(
'wpload_works_details',
'制作情報',
'wpload_render_works_meta_box',
'works',
'normal',
'default'
);
}
add_action( 'add_meta_boxes', 'wpload_add_works_meta_box' );第4引数のworksは表示対象の投稿タイプです。通常投稿や固定ページには表示されません。
入力欄とnonceを表示する
function wpload_render_works_meta_box( $post ) {
$scope = get_post_meta( $post->ID, '_wpload_work_scope', true );
wp_nonce_field( 'wpload_save_works_meta', 'wpload_works_nonce' );
?>
<p>
<label for="wpload-work-scope">担当範囲</label>
</p>
<p>
<input
id="wpload-work-scope"
name="wpload_work_scope"
type="text"
value="<?php echo esc_attr( $scope ); ?>"
class="widefat"
>
</p>
<p class="description">例:デザイン、コーディング、WordPress構築</p>
<?php
}メタキーをアンダースコアから始めると、WordPress標準のカスタムフィールド欄には通常表示されません。nonceは、意図した管理画面から送られた処理か確認するために使います。
次の画像は、「入力欄とnonceを表示する」で扱うコードや構成をブラウザで表示した結果です。

安全を確認して保存する
function wpload_save_works_meta( $post_id ) {
if ( ! isset( $_POST['wpload_works_nonce'] ) ) {
return;
}
$nonce = sanitize_text_field( wp_unslash( $_POST['wpload_works_nonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'wpload_save_works_meta' ) ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( 'works' !== get_post_type( $post_id ) ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( ! isset( $_POST['wpload_work_scope'] ) ) {
return;
}
$scope = sanitize_text_field( wp_unslash( $_POST['wpload_work_scope'] ) );
if ( '' === $scope ) {
delete_post_meta( $post_id, '_wpload_work_scope' );
return;
}
update_post_meta( $post_id, '_wpload_work_scope', $scope );
}
add_action( 'save_post_works', 'wpload_save_works_meta' );nonceの確認だけでは権限確認になりません。current_user_can()も使い、編集権限のある利用者だけが保存できるようにします。
次の図では、「安全を確認して保存する」の仕組みや関係を確認できます。

詳細ページへ表示する
保存した制作情報は、未入力時を考慮しながら詳細ページへ分かりやすく表示します。

<?php
$scope = get_post_meta( get_the_ID(), '_wpload_work_scope', true );
?>
<?php if ( '' !== $scope ) : ?>
<dl class="work-details">
<div>
<dt>担当範囲</dt>
<dd><?php echo esc_html( $scope ); ?></dd>
</div>
</dl>
<?php endif; ?>保存時に無害化していても、出力する場所に合わせてエスケープします。文章として表示するためesc_html()を使います。URLならesc_url()、HTML属性ならesc_attr()を使います。
入力と更新を確認する
- 担当範囲を入力して更新する
- 管理画面を再読み込みし、値が残っているか確認する
- 詳細ページへ値が表示されるか確認する
- HTMLに見える文字を入力し、そのまま文字として表示されるか確認する
- 値を空にして更新し、表示欄ごと消えるか確認する
- 別の権限のユーザーで入力欄と保存可否を確認する
項目が増えたら、入力形式、必須か任意か、誰が編集できるか、一覧やREST APIにも必要かを項目ごとに設計します。
次の図では、「入力と更新を確認する」の仕組みや関係を確認できます。
