2026年9月21日
2026年9月21日
WordPress Settings APIで管理画面設定ページを実装する方法
はじめに
WordPress Settings APIは、プラグインや子テーマの設定ページを管理画面に安全に実装するための公式フレームワークです。nonceの自動生成・設定の保存・エラー表示など、設定ページに必要な機能が組み込まれており、セキュリティと一貫したUIを同時に実現できます。本記事では、設定メニューの追加から各フィールドの実装まで段階的に解説します。
症状・原因
- プラグインの設定ページを手動で実装しているが、nonceの処理や保存ロジックが複雑になっている
- 設定ページのUIがWordPress標準のデザインと一致せず、管理画面で違和感がある
- 複数の設定セクションとフィールドを整理された形で管理する方法がわからない
解決手順
ステップ1:add_options_page()で管理メニューを追加する
<?php
/**
* 管理画面メニューの追加
*/
add_action( 'admin_menu', 'my_plugin_add_menu' );
function my_plugin_add_menu() {
// 「設定」メニューのサブページとして追加する
add_options_page(
'My Plugin 設定', // ページタイトル(<title>タグ)
'My Plugin', // メニューに表示されるラベル
'manage_options', // このページを表示できる権限
'my-plugin-settings', // メニュースラッグ(URLの一部)
'my_plugin_settings_page' // 設定ページを出力するコールバック関数
);
// カスタムメニューに追加する場合は add_menu_page() を使用
// add_menu_page(
// 'My Plugin',
// 'My Plugin',
// 'manage_options',
// 'my-plugin',
// 'my_plugin_settings_page',
// 'dashicons-admin-plugins',
// 80
// );
// サブメニューを追加する場合
// add_submenu_page(
// 'my-plugin', // 親メニューのスラッグ
// 'My Plugin 詳細設定',
// '詳細設定',
// 'manage_options',
// 'my-plugin-advanced',
// 'my_plugin_advanced_page'
// );
}
ステップ2:register_setting()でサニタイズコールバックを登録する
<?php
/**
* 設定の登録(admin_init フックで実行)
*/
add_action( 'admin_init', 'my_plugin_register_settings' );
function my_plugin_register_settings() {
// メイングループの設定を登録
register_setting(
'my_plugin_options_group', // オプショングループ名(settings_fields() で使用)
'my_plugin_general', // オプション名(wp_options に保存されるキー)
array(
'sanitize_callback' => 'my_plugin_sanitize_general',
'default' => array(
'site_title' => '',
'enable_logging' => false,
'log_level' => 'error',
),
)
);
// 詳細設定グループ
register_setting(
'my_plugin_options_group',
'my_plugin_advanced',
array(
'sanitize_callback' => 'my_plugin_sanitize_advanced',
)
);
}
/**
* 一般設定のサニタイズ
*/
function my_plugin_sanitize_general( $input ) {
$output = array();
$output['site_title'] = sanitize_text_field( $input['site_title'] ?? '' );
$output['enable_logging'] = ! empty( $input['enable_logging'] );
$allowed_levels = array( 'debug', 'info', 'warning', 'error' );
$output['log_level'] = in_array( $input['log_level'] ?? '', $allowed_levels, true )
? $input['log_level']
: 'error';
return $output;
}
ステップ3:add_settings_section()でセクションを追加する
<?php
/**
* 設定セクションの追加
* ※ admin_init フック内で register_setting() と一緒に実行する
*/
function my_plugin_register_settings() {
// ... register_setting() の後に続けて記述 ...
// === 一般設定セクション ===
add_settings_section(
'my_plugin_general_section', // セクションID
'一般設定', // セクションのタイトル
'my_plugin_general_section_callback', // セクション説明文のコールバック
'my-plugin-settings' // このセクションが属するページスラッグ
);
// === 詳細設定セクション ===
add_settings_section(
'my_plugin_advanced_section',
'詳細設定',
'my_plugin_advanced_section_callback',
'my-plugin-settings'
);
}
/**
* セクション説明文の出力コールバック
*/
function my_plugin_general_section_callback() {
echo '<p>プラグインの基本的な動作を設定します。</p>';
}
function my_plugin_advanced_section_callback() {
echo '<p>上級者向けの詳細設定です。変更は慎重に行ってください。</p>';
}
ステップ4:add_settings_field()でフィールドを追加する
<?php
/**
* 設定フィールドの追加
*/
function my_plugin_register_settings() {
// ... セクション登録の後に続けて記述 ...
// テキストフィールド
add_settings_field(
'my_plugin_site_title', // フィールドID
'サイト表示名', // フィールドラベル
'my_plugin_field_site_title', // フィールドHTMLを出力するコールバック
'my-plugin-settings', // ページスラッグ
'my_plugin_general_section', // 属するセクションID
array( 'label_for' => 'my_plugin_site_title' ) // <label>のfor属性と紐付ける
);
// チェックボックス
add_settings_field(
'my_plugin_enable_logging',
'ログ記録',
'my_plugin_field_enable_logging',
'my-plugin-settings',
'my_plugin_general_section'
);
// セレクトボックス
add_settings_field(
'my_plugin_log_level',
'ログレベル',
'my_plugin_field_log_level',
'my-plugin-settings',
'my_plugin_general_section'
);
}
/**
* テキストフィールドのコールバック
*/
function my_plugin_field_site_title() {
$options = get_option( 'my_plugin_general', array() );
$value = isset( $options['site_title'] ) ? $options['site_title'] : '';
?>
<input type="text"
id="my_plugin_site_title"
name="my_plugin_general[site_title]"
value="<?php echo esc_attr( $value ); ?>"
class="regular-text"
placeholder="例:ワードプレス博士">
<p class="description">フロントエンドに表示されるサイト名です。</p>
<?php
}
/**
* チェックボックスのコールバック
*/
function my_plugin_field_enable_logging() {
$options = get_option( 'my_plugin_general', array() );
$checked = ! empty( $options['enable_logging'] );
?>
<label>
<input type="checkbox"
name="my_plugin_general[enable_logging]"
value="1"
<?php checked( $checked ); ?>>
ログ記録を有効にする
</label>
<p class="description">有効にするとデバッグログが記録されます。</p>
<?php
}
/**
* セレクトボックスのコールバック
*/
function my_plugin_field_log_level() {
$options = get_option( 'my_plugin_general', array() );
$current = isset( $options['log_level'] ) ? $options['log_level'] : 'error';
$choices = array(
'debug' => 'デバッグ(すべて記録)',
'info' => '情報',
'warning' => '警告',
'error' => 'エラーのみ',
);
?>
<select id="my_plugin_log_level" name="my_plugin_general[log_level]">
<?php foreach ( $choices as $value => $label ) : ?>
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $current, $value ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
ステップ5:settings_fields/do_settings_sectionsとsettings_errorsで設定フォームを完成させる
<?php
/**
* 設定ページのHTMLを出力するコールバック
*/
function my_plugin_settings_page() {
// 権限チェック
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'このページへのアクセス権限がありません。', 'my-plugin' ) );
}
?>
<div class="wrap">
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<?php
// 設定保存後のメッセージを表示する
// 'updated' クラスの成功メッセージと 'error' クラスのエラーメッセージを自動出力
settings_errors( 'my_plugin_options_group' );
?>
<form method="post" action="options.php">
<?php
/**
* settings_fields(): 以下を自動出力する
* - hidden フィールド(option_page, action)
* - nonce フィールド(CSRF対策)
* - _wp_http_referer フィールド
*/
settings_fields( 'my_plugin_options_group' );
/**
* do_settings_sections(): 指定ページの全セクション・全フィールドを出力する
* - <table> 形式で各フィールドが整列して表示される
*/
do_settings_sections( 'my-plugin-settings' );
// 送信ボタンを出力(WordPressスタイルに準拠)
submit_button( '設定を保存' );
?>
</form>
<?php
// カスタムエラーメッセージの追加例(settings_errors() で表示される)
// add_settings_error(
// 'my_plugin_options_group',
// 'my_plugin_error',
// 'APIキーが無効です。正しいキーを入力してください。',
// 'error'
// );
?>
</div>
<?php
}
注意事項
settings_fields()は必須: フォーム内でsettings_fields()を呼び忘れると、nonceが生成されず設定が保存されません- オプショングループ名の一致:
register_setting()・settings_fields()・do_settings_sections()で使用するグループ名とページスラッグを一致させてください do_settings_sections()の引数:add_settings_section()・add_settings_field()の第4引数(ページスラッグ)と同じ文字列を渡す必要があります- カスタムフォームレイアウト:
do_settings_sections()の代わりにdo_settings_fields()を使うと、テーブルレイアウトを使わずカスタムレイアウトで各フィールドを出力できます
まとめ
Settings APIは「登録→セクション追加→フィールド追加→フォーム出力」の4ステップで、安全で標準的な管理画面設定ページを実装できます。settings_fields()によるnonce自動処理とdo_settings_sections()による一括出力により、手動実装に比べてコード量を大幅に削減できます。関連記事:WordPress管理画面ダッシュボードにカスタムウィジェットを追加する方法