2026年5月20日

2026年5月20日

WordPressのテーマオプションページを作る方法

はじめに

テーマオプションページを管理画面に追加することで、コードを触らずにサイト設定(フッターテキスト・SNSリンク・テーマカラーなど)を変更できる仕組みを提供できます。Settings APIを使うことで安全なオプション保存が実装できます。

症状・原因

  • テーマの設定をコードを書かずに変更したい
  • 管理画面にカスタム設定ページを追加したい
  • get_option でテーマ設定を取得したい
  • フッターテキストやSNSアカウントをUIで設定できるようにしたい

解決手順

ステップ1:メニューページを登録する

// functions.php
function mytheme_add_options_page(): void {
    add_menu_page(
        'テーマ設定',           // ページタイトル
        'テーマ設定',           // メニュータイトル
        'manage_options',       // 権限
        'mytheme-options',      // スラッグ(メニューID)
        'mytheme_options_page', // コールバック関数
        'dashicons-admin-appearance', // アイコン
        60                      // 位置(60=外観の後)
    );
}
add_action('admin_menu', 'mytheme_add_options_page');

サブメニューに追加する場合:

function mytheme_add_submenu(): void {
    add_submenu_page(
        'themes.php',           // 親メニュー(外観)
        'テーマ設定',
        'テーマ設定',
        'manage_options',
        'mytheme-options',
        'mytheme_options_page'
    );
}
add_action('admin_menu', 'mytheme_add_submenu');

ステップ2:Settings APIでオプションを登録する

// functions.php
function mytheme_register_settings(): void {
    // オプショングループを登録
    register_setting(
        'mytheme_options_group',    // グループ名
        'mytheme_options',          // オプション名(DBに保存されるキー)
        [
            'sanitize_callback' => 'mytheme_sanitize_options',
            'default'           => mytheme_get_default_options(),
        ]
    );

    // セクションを追加
    add_settings_section(
        'mytheme_general_section',
        '基本設定',
        '__return_false', // セクション説明なし
        'mytheme-options'
    );

    add_settings_section(
        'mytheme_sns_section',
        'SNS設定',
        '__return_false',
        'mytheme-options'
    );

    // フィールドを追加
    add_settings_field(
        'footer_text',
        'フッターテキスト',
        'mytheme_footer_text_field',
        'mytheme-options',
        'mytheme_general_section'
    );

    add_settings_field(
        'twitter_url',
        'Twitter URL',
        'mytheme_twitter_url_field',
        'mytheme-options',
        'mytheme_sns_section'
    );
}
add_action('admin_init', 'mytheme_register_settings');

function mytheme_get_default_options(): array {
    return [
        'footer_text' => '© ' . date('Y') . ' ' . get_bloginfo('name'),
        'twitter_url' => '',
        'facebook_url' => '',
        'primary_color' => '#2271b1',
    ];
}

ステップ3:フィールドのコールバック関数を定義する

// functions.php
function mytheme_footer_text_field(): void {
    $options = get_option('mytheme_options', mytheme_get_default_options());
    $value   = $options['footer_text'] ?? '';
    ?>
    <input
        type="text"
        name="mytheme_options[footer_text]"
        id="footer_text"
        value="<?php echo esc_attr($value); ?>"
        class="regular-text"
    >
    <p class="description">フッターに表示するコピーライト文を入力してください。</p>
    <?php
}

function mytheme_twitter_url_field(): void {
    $options = get_option('mytheme_options', mytheme_get_default_options());
    $value   = $options['twitter_url'] ?? '';
    ?>
    <input
        type="url"
        name="mytheme_options[twitter_url]"
        id="twitter_url"
        value="<?php echo esc_url($value); ?>"
        class="regular-text"
        placeholder="https://twitter.com/your-account"
    >
    <?php
}

ステップ4:設定ページのHTMLを出力する

// functions.php
function mytheme_options_page(): void {
    if (!current_user_can('manage_options')) {
        return;
    }
    ?>
    <div class="wrap">
        <h1><?php echo esc_html(get_admin_page_title()); ?></h1>

        <?php settings_errors('mytheme_options'); ?>

        <form action="options.php" method="post">
            <?php
            settings_fields('mytheme_options_group');
            do_settings_sections('mytheme-options');
            submit_button('設定を保存');
            ?>
        </form>
    </div>
    <?php
}

ステップ5:サニタイズ関数を実装する

// functions.php
function mytheme_sanitize_options(array $input): array {
    $sanitized = mytheme_get_default_options();

    if (isset($input['footer_text'])) {
        $sanitized['footer_text'] = sanitize_text_field($input['footer_text']);
    }

    if (isset($input['twitter_url'])) {
        $sanitized['twitter_url'] = esc_url_raw($input['twitter_url']);
    }

    if (isset($input['primary_color'])) {
        // カラーコードのバリデーション
        $color = sanitize_hex_color($input['primary_color']);
        $sanitized['primary_color'] = $color ?: '#2271b1';
    }

    return $sanitized;
}

ステップ6:テンプレートで設定値を取得する

// footer.php など
$options = get_option('mytheme_options', mytheme_get_default_options());

// フッターテキスト
echo wp_kses_post($options['footer_text'] ?? '');

// SNSリンク
if (!empty($options['twitter_url'])) {
    printf(
        '<a href="%s" target="_blank" rel="noopener noreferrer">Twitter</a>',
        esc_url($options['twitter_url'])
    );
}

注意事項

  • Settings APIを使わずに直接 update_option を呼ぶ実装はnonce検証・サニタイズ漏れの原因になります。必ずSettings APIを通してください
  • manage_options 権限チェックを mytheme_options_page の先頭で必ず行ってください
  • テーマオプションが多い場合はカスタマイザー(add_setting/add_control)の利用も検討してください。リアルタイムプレビューが使えます

まとめ

add_menu_page で管理画面にページを追加し、register_settingadd_settings_sectionadd_settings_field でSettings APIを構築します。フォームは settings_fields + do_settings_sections + submit_button で出力し、サニタイズ関数でセキュアに保存します。値の取得は get_option('mytheme_options') で行います。

お気軽にご相談ください

お見積りへ お問い合わせへ