2026年10月7日
2026年10月7日
WordPressのユーザープロフィール画面をカスタマイズするコード例|項目の追加・保存・検証・非表示
WordPress の管理画面の「プロフィール」「ユーザー編集」画面は、表示用のアクションフックで入力欄を足し、保存用のアクションフックでユーザーメタに書き込む、という組み合わせでカスタマイズできます。この記事では、連絡先欄の追加、独自項目の追加と保存、入力値の検証、不要な項目を隠す方法、フロント側での表示までを、そのまま使えるコード例で説明します。
使うフックの全体像
プロフィール画面は、自分のプロフィールを開く場合と、管理者がほかのユーザーを編集する場合で、呼ばれるフックが分かれています。両方に同じ処理を登録するのが基本です。
| 目的 | 自分のプロフィール | 他ユーザーの編集 |
|---|---|---|
| 入力欄を表示する | show_user_profile |
edit_user_profile |
| 値を保存する | personal_options_update |
edit_user_profile_update |
このほか、入力値の検証には user_profile_update_errors、「ユーザーを新規追加」画面に欄を出すには user_new_form、連絡先欄を手軽に増やすには user_contactmethods フィルターを使います。
コードはテーマの functions.php ではなく、子テーマか mu-plugin(wp-content/mu-plugins/ に置く PHP ファイル)に書くと、親テーマの更新やテーマ変更で消えません。作業前にバックアップを取り、ステージング環境で試してから本番に反映してください。
例1:連絡先欄を追加する(最も手軽な方法)
X(旧 Twitter)のアカウントや所属のような「1行のテキスト」で済む項目なら、user_contactmethods フィルターだけで足ります。表示と保存は WordPress が受け持ってくれます。
add_filter( 'user_contactmethods', function ( $methods ) {
$methods['x_account'] = 'X(旧Twitter)のアカウント';
$methods['company'] = '所属';
return $methods;
} );
保存された値はユーザーメタに入り、get_the_author_meta( 'x_account', $user_id ) や get_user_meta( $user_id, 'x_account', true ) で取り出せます。手軽な反面、入力形式の検証や選択肢の指定はできないので、それが必要なら次の方法を使います。
例2:独自の項目を追加して保存する
ここでは「連絡先の電話番号(テキスト)」と「著者ページに表示するか(チェックボックス)」を追加します。
<?php
/**
* Plugin Name: Custom Profile Fields
* wp-content/mu-plugins/custom-profile-fields.php に置く。
*/
// 表示: 自分のプロフィール / 他ユーザーの編集の両方
add_action( 'show_user_profile', 'cpf_render_fields' );
add_action( 'edit_user_profile', 'cpf_render_fields' );
function cpf_render_fields( WP_User $user ) {
$phone = get_user_meta( $user->ID, 'cpf_phone', true );
$show = get_user_meta( $user->ID, 'cpf_show_on_author_page', true );
wp_nonce_field( 'cpf_save_' . $user->ID, 'cpf_nonce' );
?>
<h2>追加情報</h2>
<table class="form-table" role="presentation">
<tr>
<th><label for="cpf_phone">連絡先の電話番号</label></th>
<td>
<input type="tel" name="cpf_phone" id="cpf_phone"
value="<?php echo esc_attr( $phone ); ?>" class="regular-text">
<p class="description">半角の数字・ハイフン・スペースで入力します。国番号を付ける場合は先頭に + を付けます。</p>
</td>
</tr>
<tr>
<th>著者ページ</th>
<td>
<label>
<input type="checkbox" name="cpf_show_on_author_page" value="1" <?php checked( $show, '1' ); ?>>
著者ページにプロフィールを表示する
</label>
</td>
</tr>
</table>
<?php
}
// 保存
add_action( 'personal_options_update', 'cpf_save_fields' );
add_action( 'edit_user_profile_update', 'cpf_save_fields' );
function cpf_save_fields( $user_id ) {
if ( ! current_user_can( 'edit_user', $user_id ) ) {
return;
}
if ( ! isset( $_POST['cpf_nonce'] )
|| ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cpf_nonce'] ) ), 'cpf_save_' . $user_id ) ) {
return;
}
$phone = isset( $_POST['cpf_phone'] )
? sanitize_text_field( wp_unslash( $_POST['cpf_phone'] ) )
: '';
if ( cpf_is_valid_phone( $phone ) ) { // 検証関数は例3で定義
update_user_meta( $user_id, 'cpf_phone', $phone );
}
$show = ! empty( $_POST['cpf_show_on_author_page'] ) ? '1' : '0';
update_user_meta( $user_id, 'cpf_show_on_author_page', $show );
}
コードの要点を補足します。
- 権限チェック:
edit_user権限で「このユーザーを編集してよいか」を確認します。コアのプロフィール画面も保存前に権限と nonce を確認していますが、フックはほかの経路から呼ばれることもあるため、自分の処理でも確認しておくのが安全です。 - nonce:独自の nonce を出力して検証しています。値は
wp_unslash()してから使います。 - サニタイズとエスケープ:保存時は
sanitize_text_field()、表示時はesc_attr()を使います。複数行ならsanitize_textarea_field()、URL ならesc_url_raw()(保存)とesc_url()(表示)に替えてください。 - チェックボックス:チェックを外すと値が送信されないので、未送信を「0」として明示的に保存しています。
保存関数の中で呼んでいる cpf_is_valid_phone() は例3で定義するので、例2と例3は同じファイルに置いてください。メタキーには cpf_ のような接頭辞を付け、ほかのプラグインと名前がぶつからないようにします。
確認は、自分のプロフィールと、別ユーザーの編集画面の両方で値を保存し、再読み込み後に残っているかを見ます。編集者など管理者以外のロールでもログインして、ほかのユーザーの画面を開けない(保存できない)ことも確かめてください。
例3:入力値を検証してエラーを出す
入力の形式をチェックし、不正なら画面上部にエラーを出すには user_profile_update_errors を使います。このアクションは WP_Error オブジェクトを受け取り、エラーを追加すると、氏名やメールアドレスなどコアの項目の更新が中止されてエラーが表示されます。
ここでは電話番号を「先頭に + を1つまで付けてよく、数字で始まり、数字・ハイフン・スペースで合計7〜20文字」という単純な規則で確かめます。国や用途によって必要な形式は違うので、正規表現は自分のサイトに合わせて変えてください。
// 空欄は許可し、入力がある場合だけ形式を確かめる
// 先頭に + を1つまで、数字で始まり、数字・ハイフン・スペースで合計7〜20文字
function cpf_is_valid_phone( $phone ) {
return '' === $phone || 1 === preg_match( '/\A\+?[0-9][0-9\- ]{6,19}\z/', $phone );
}
add_action( 'user_profile_update_errors', function ( $errors, $update, $user ) {
if ( ! isset( $_POST['cpf_phone'] ) ) {
return; // この欄を出していない画面(新規追加など)では何もしない
}
$phone = sanitize_text_field( wp_unslash( $_POST['cpf_phone'] ) );
if ( ! cpf_is_valid_phone( $phone ) ) {
$errors->add( 'cpf_phone', '電話番号は半角の数字・ハイフン・スペースで入力してください。' );
}
}, 10, 3 );
この規則では、03-1234-5678 や +81 3 1234 5678 は通り、abc や 12-34 は通りません。
注意したいのは実行の順番です。プロフィール画面(wp-admin/user-edit.php)では、例2の保存用フック(personal_options_update / edit_user_profile_update)が先に実行され、そのあとでコアの更新処理(edit_user())と user_profile_update_errors が呼ばれます。つまり、ここでエラーを出しても独自項目の保存そのものは止まりません。そのため例2の保存関数でも同じ検証関数を呼び、不正な値は保存しないようにしています。検証のロジックを1つの関数にまとめておくと、表示と保存で判定がずれません。
例4:不要な項目を隠す
一般ユーザーに管理画面のプロフィールを見せる会員サイトでは、項目を減らしたいことがあります。管理画面の配色の選択は、コアがアクション(admin_color_scheme_picker)として登録しているので外せます。
add_action( 'admin_init', function () {
if ( ! current_user_can( 'manage_options' ) ) {
remove_action( 'admin_color_scheme_picker', 'admin_color_scheme_picker' );
}
} );
それ以外の項目(Web サイト、プロフィール情報など)は専用のフックが無いものが多く、CSS で見た目だけ隠す方法がよく紹介されます。ただし CSS で隠しても値は送信・保存できるので、「変更させたくない」項目の制限にはなりません。変更を防ぎたいなら、保存時に元の値へ戻す処理を書くか、管理画面のプロフィールを見せずにフロント側の編集フォームを用意するほうが確かです。フロント側の編集画面は Ultimate Member や Profile Builder などのプラグインでも作れますが、機能の範囲は無料版と有償版で異なるため、導入前に公式の説明を確認してください(2026年10月時点)。
例5:保存した値をフロントに表示する
著者アーカイブ(author.php)や記事のテンプレートから呼び出す関数の例です。著者アーカイブでは表示中の著者、記事の中ではその記事の著者を対象にします。
function cpf_author_box() {
$author_id = is_author() ? get_queried_object_id() : (int) get_the_author_meta( 'ID' );
if ( '1' === get_user_meta( $author_id, 'cpf_show_on_author_page', true ) ) {
$phone = get_user_meta( $author_id, 'cpf_phone', true );
if ( $phone ) {
echo '<p class="author-phone">' . esc_html( $phone ) . '</p>';
}
}
}
テンプレートの表示したい位置で cpf_author_box(); を呼びます。出力時は毎回エスケープします。ブロックテーマでは PHP テンプレートを直接編集しないため、ショートコードや独自ブロックとして表示部分を作る形になります。
電話番号のようにユーザーが入力したプロフィール情報は個人データです。公開するのは本人が「著者ページに表示する」を選んだ場合だけにするなど、何を集めて何に使うか、公開されるのはどの項目かをプライバシーポリシーに書いておきましょう。
まとめ
- 表示は
show_user_profileとedit_user_profile、保存はpersonal_options_updateとedit_user_profile_updateの両方に登録する。 - 1行テキストの連絡先なら
user_contactmethodsフィルターだけで足りる。 - 保存処理では
edit_user権限と nonce を確認し、保存時にサニタイズ、表示時にエスケープする。 - エラー表示は
user_profile_update_errorsで行うが、保存用フックが先に動くので保存関数でも同じ検証をする。 - CSS で隠すのは見た目だけで、変更の制限にはならない。
- コードは子テーマか mu-plugin に置き、ステージングで権限ごとに動作を確かめる。