1. ホーム
  2. WordPress

【WordPress】Settings API(register_setting)で設定ページを作る方法

Share

WordPress のテーマやプラグインを作っていると、「管理画面に独自の設定ページを作って、そこで入力した値を保存・取得したい」という場面が出てきます。これを正しく実現するための仕組みが Settings API です。この記事では、add_options_page() で設定ページを追加し、register_setting()add_settings_field() でフィールドを登録、do_settings_sections() でフォームを描画して、get_option() で値を取り出すまでの流れを、動くコードとともに解説します。

Settings API とは

Settings API は、WordPress の管理画面に設定ページを作るための公式な仕組みです。フォームの送信先や保存処理、入力値の検証(サニタイズ)まで WordPress がまとめて面倒を見てくれるため、自分で $_POST を受け取って保存する処理を書く必要がありません。

値の保存先は get_option() / update_option() と同じ wp_options テーブルです。つまり「設定の保存・取得」自体はオプション関数と同じで、Settings API はその入力フォームと保存処理を安全に組み立てるためのレールだと考えると分かりやすいです。自前のフォームで update_option() を呼ぶよりも、サニタイズや nonce(不正送信対策)の扱いを WordPress に任せられるのが大きな利点です。

登場する関数とその役割

最初に、これから使う関数を整理しておきます。役割を頭に入れておくと、後のコードがぐっと読みやすくなります。

関数役割
add_options_page()「設定」メニューの下に設定ページを追加する
add_menu_page()管理画面の最上位に独立したメニューを追加する
register_setting()保存するオプション(設定値)を登録し、サニタイズ方法を指定する
add_settings_section()設定項目をまとめるセクション(区切り)を追加する
add_settings_field()個々の入力フィールドを登録し、描画する関数を指定する
settings_fields()フォームに nonce などの隠しフィールドを出力する
do_settings_sections()登録済みのセクションとフィールドをまとめて描画する
get_option()保存された設定値を取得する

設定ページを追加する

まずは管理画面に設定ページそのものを追加します。「設定」メニューの中に置きたい場合は add_options_page()admin_menu フックで呼び出します。

functions.php
<?php
// 「設定」メニューの下に設定ページを追加する
function mytheme_add_settings_page() {
    add_options_page(
        'My Theme 設定',        // ブラウザのタイトル(<title>)
        'My Theme 設定',        // メニューに表示するラベル
        'manage_options',       // 表示に必要な権限
        'mytheme-settings',     // ページを識別するスラッグ
        'mytheme_render_settings_page' // ページ本体を描画する関数
    );
}
add_action( 'admin_menu', 'mytheme_add_settings_page' );

第3引数の 'manage_options' は、管理者だけがアクセスできるようにする権限(ケイパビリティ)です。設定ページは通常この権限で保護します。最上位に独立したメニューを作りたいときは、代わりに add_menu_page() を使います。引数の構成は似ていますが、アイコンや表示順を指定できる点が異なります。

保存する設定とフィールドを登録する

次に、保存する設定(オプション)と、その入力欄を登録します。これらは admin_init フックの中でまとめて行うのが定番です。register_setting() で「何を保存するか」を、add_settings_section()add_settings_field() で「どんな見た目で入力させるか」を定義していきます。

functions.php
<?php
function mytheme_register_settings() {
    // 1. 保存するオプションを登録する
    register_setting(
        'mytheme_settings_group', // 設定グループ名(settings_fields で使う)
        'mytheme_site_subtitle',  // wp_options に保存されるオプション名
        array(
            'type'              => 'string',
            'sanitize_callback' => 'sanitize_text_field', // 入力値の整形
            'default'           => '',
        )
    );

    // 2. 設定項目をまとめるセクションを追加する
    add_settings_section(
        'mytheme_main_section',          // セクションID
        '基本設定',                      // 見出し
        'mytheme_main_section_callback', // 説明文を描画する関数
        'mytheme-settings'               // 表示するページのスラッグ
    );

    // 3. 入力フィールドを追加する
    add_settings_field(
        'mytheme_site_subtitle',        // フィールドID
        'サイトのサブタイトル',          // ラベル
        'mytheme_subtitle_field_render', // 入力欄を描画する関数
        'mytheme-settings',             // 表示するページのスラッグ
        'mytheme_main_section'          // 所属するセクションID
    );
}
add_action( 'admin_init', 'mytheme_register_settings' );

// セクションの説明文
function mytheme_main_section_callback() {
    echo '<p>サイト全体で使う基本的な設定です。</p>';
}

// 入力欄(テキストボックス)を描画する
function mytheme_subtitle_field_render() {
    // 現在保存されている値を取得する
    $value = get_option( 'mytheme_site_subtitle', '' );
    printf(
        '<input type="text" name="%s" value="%s" class="regular-text">',
        'mytheme_site_subtitle',
        esc_attr( $value )
    );
}

ポイントは、register_setting() の第1引数で指定した設定グループ名(ここでは 'mytheme_settings_group')と、第2引数のオプション名'mytheme_site_subtitle')です。グループ名は後でフォームに settings_fields() で渡し、オプション名は get_option() で値を取り出すときに使います。フィールドを描画する関数の中で name 属性をオプション名と一致させておくことで、送信した値がそのオプションに保存されます。

フォームを描画する

最後に、設定ページ本体を描画する関数を用意します。add_options_page() の第5引数で指定した mytheme_render_settings_page() がそれです。ここで settings_fields()do_settings_sections() を呼ぶだけで、登録済みのフィールドとフォームの保存処理が一気に組み上がります。

functions.php
<?php
function mytheme_render_settings_page() {
    // 権限のないユーザーは弾く
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?>
    <div class="wrap">
        <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
        <form action="options.php" method="post">
            <?php
            // nonce や隠しフィールドを出力する(設定グループ名を渡す)
            settings_fields( 'mytheme_settings_group' );

            // 登録済みのセクションとフィールドを描画する
            do_settings_sections( 'mytheme-settings' );

            // 保存ボタンを描画する
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

フォームの送信先(action)が options.php になっている点に注目してください。Settings API を使う場合、フォームはこの options.php に送信します。送られた値は WordPress が register_setting() の登録情報をもとに自動で保存してくれるため、自分で保存処理を書く必要はありません。submit_button() は「変更を保存」ボタンを出力するヘルパー関数です。

保存した値を取り出して使う

設定ページで保存した値は、get_option() にオプション名を渡すだけで、テーマやプラグインのどこからでも取り出せます。第2引数には、値がまだ保存されていないときに返すデフォルト値を指定できます。

header.php
<?php
// 保存されたサブタイトルを取得して表示する
$subtitle = get_option( 'mytheme_site_subtitle', '' );

if ( $subtitle !== '' ) {
    // 出力時は必ずエスケープする
    echo '<p class="site-subtitle">' . esc_html( $subtitle ) . '</p>';
}

このように、設定ページで入力した値が get_option() でそのまま読み出せます。値を画面に出力するときは、保存時にサニタイズしていても esc_html()esc_attr() でエスケープするのが安全です。

register_setting のサニタイズコールバックを理解する

register_setting() の引数で指定する sanitize_callback は、フォームから送られてきた値を保存する直前に整形・検証する関数です。ユーザーが入力した値をそのまま保存すると、不正なタグや想定外の文字列が混ざる可能性があるため、ここで安全な形に整えます。

1行のテキストなら sanitize_text_field、メールアドレスなら sanitize_email、整数なら absint のように、保存したい値の種類に合ったコールバックを指定します。標準の関数で足りない場合は、自分で関数を作って渡すこともできます。

functions.php
<?php
// 独自のサニタイズ関数を指定する例
register_setting(
    'mytheme_settings_group',
    'mytheme_max_items',
    array(
        'type'              => 'integer',
        'sanitize_callback' => 'mytheme_sanitize_max_items',
        'default'           => 5,
    )
);

// 1〜100 の範囲に収める
function mytheme_sanitize_max_items( $value ) {
    $value = absint( $value ); // 0以上の整数に変換
    if ( $value < 1 ) {
        $value = 1;
    } elseif ( $value > 100 ) {
        $value = 100;
    }
    return $value;
}

コールバックは送信された値を受け取り、整形した値を return で返します。返した値がそのまま wp_options に保存されるため、ここで範囲チェックや型変換をしておけば、不正な値が保存されるのを防げます。サニタイズコールバックの指定はオプションではなく、データを安全に扱うための必須の習慣だと考えてください。

nonce は Settings API が自動で処理する

フォームを自作する場合は、不正送信(CSRF)対策として wp_nonce_field() で nonce を出力し、受信側で検証する必要があります。しかし Settings API を使う場合、この処理は settings_fields() が自動で行います

settings_fields() は、設定グループ名に対応した nonce や option_page といった隠しフィールドをまとめて出力します。そして送信先の options.php 側で、WordPress がその nonce を検証してくれます。そのため、開発者が自分で nonce の生成・検証を書く必要はありません。settings_fields() の呼び忘れがあると保存が正しく行われないので、フォームの中に必ず入れておきましょう。

設定が保存されないときに確認すること

設定グループ名がそろっていない

もっとも多いのが、register_setting() の第1引数と settings_fields() に渡す名前が一致していないケースです。この2つは同じ設定グループ名(例では 'mytheme_settings_group')でなければなりません。タイプミスがあると、送信された値が登録済みのオプションと結び付かず、保存されません。

ページのスラッグが食い違っている

add_settings_section()add_settings_field() の「表示するページ」の引数と、do_settings_sections() に渡すスラッグ(例では 'mytheme-settings')が一致していないと、フィールドが画面に表示されません。フィールドが出てこないときは、まずこのスラッグがそろっているか確認しましょう。

フォームの送信先が options.php になっていない

Settings API による保存は、フォームを options.php に送信することで初めて動きます。action 属性を自分のページのURLにしてしまうと、WordPress の保存処理が走らず値が消えてしまいます。<form action="options.php" method="post"> になっているか確認してください。

まとめ

Settings API を使うと、管理画面の設定ページを安全かつ定型的な流れで作れます。最後に手順を整理しておきます。

  • add_options_page() / add_menu_page() で設定ページを追加する
  • register_setting() で保存する値とサニタイズ方法を登録する
  • add_settings_section() / add_settings_field() で入力欄を組み立てる
  • フォームを options.php に送信し、settings_fields()do_settings_sections() で描画する
  • 保存した値は get_option() で取り出す

サニタイズコールバックで入力値を安全に整え、nonce の処理は settings_fields() に任せられるのが Settings API の強みです。自前のフォームで update_option() を呼ぶ方法と比べて、安全で保守しやすい設定画面が作れます。まずはテキスト1項目の設定ページから試してみてください。

参考リンク