2026年5月20日

2026年5月20日

WordPressのカスタマイザーAPIの使い方:設定項目の追加とリアルタイムプレビュー

カスタマイザー(「外観」→「カスタマイズ」)は、画面右側でプレビューを見ながらテーマの設定を変えられる機能です。テーマは customize_register フックで、ここに独自の設定項目を追加できます。

この記事のコードは、2026年11月時点の WordPress 6.9 と PHP 8.3 で構文を確かめています。

使う前に知っておくこと

  • ブロックテーマでは基本的に表示されません。 Twenty Twenty-Five などのブロックテーマが有効なとき、「外観」メニューに「カスタマイズ」は出ません。ただし、テーマやプラグインが customize_register フックを使っている場合は表示されます。ブロックテーマの色や文字の設定は、サイトエディターと theme.json で扱うのが基本です。
  • 設定はテーマごとに保存されます。 後で説明する get_theme_mod() の値はテーマごとに保存されるため、別のテーマに切り替えると引き継がれません。

4つの部品の関係

部品 追加するメソッド 役割
パネル add_panel() 複数のセクションをまとめる入れ物(無くてもよい)
セクション add_section() 画面に並ぶ1つのグループ
設定(セッティング) add_setting() 保存する値。初期値・無害化の関数・プレビューの方法を決める
コントロール add_control() 設定を入力する部品(テキスト欄、色の選択など)

コントロールが1つも無いセクションと、そのようなセクションしか無いパネルは画面に表示されません。追加したのに出てこない場合は、まずコントロールの section の指定を確かめてください。

設定項目を追加する

functions.php に書く例です。customize_register のコールバックは1つにまとめます(同じ名前の関数を2回定義すると、PHP のエラーで画面が真っ白になります)。

<?php
add_action( 'customize_register', 'mytheme_customize_register' );

function mytheme_customize_register( WP_Customize_Manager $wp_customize ) {

    // パネル
    $wp_customize->add_panel( 'mytheme_panel', array(
        'title'    => 'テーマ設定',
        'priority' => 130,
    ) );

    // セクション
    $wp_customize->add_section( 'mytheme_colors', array(
        'title' => '色とロゴ',
        'panel' => 'mytheme_panel',
    ) );
    $wp_customize->add_section( 'mytheme_layout', array(
        'title' => 'レイアウトとフッター',
        'panel' => 'mytheme_panel',
    ) );

    // 色:カラーピッカー
    $wp_customize->add_setting( 'mytheme_primary_color', array(
        'default'           => '#2271b1',
        'sanitize_callback' => 'sanitize_hex_color',
        'transport'         => 'postMessage', // JavaScript でプレビューを更新する
    ) );
    $wp_customize->add_control( new WP_Customize_Color_Control(
        $wp_customize,
        'mytheme_primary_color',
        array(
            'label'   => 'メインの色',
            'section' => 'mytheme_colors',
        )
    ) );

    // 画像:メディアライブラリから選ぶ(保存されるのは添付ファイルの ID)
    $wp_customize->add_setting( 'mytheme_banner', array(
        'default'           => 0,
        'sanitize_callback' => 'absint',
    ) );
    $wp_customize->add_control( new WP_Customize_Media_Control(
        $wp_customize,
        'mytheme_banner',
        array(
            'label'     => 'バナー画像',
            'section'   => 'mytheme_colors',
            'mime_type' => 'image',
        )
    ) );

    // 選択肢:セレクトボックス
    $wp_customize->add_setting( 'mytheme_layout', array(
        'default'           => 'sidebar-right',
        'sanitize_callback' => 'mytheme_sanitize_select',
    ) );
    $wp_customize->add_control( 'mytheme_layout', array(
        'label'   => 'サイドバーの位置',
        'section' => 'mytheme_layout',
        'type'    => 'select',
        'choices' => array(
            'sidebar-right' => '右',
            'sidebar-left'  => '左',
            'no-sidebar'    => 'なし',
        ),
    ) );

    // テキスト:フッターの文言
    $wp_customize->add_setting( 'mytheme_footer_text', array(
        'default'           => 'My Site',
        'sanitize_callback' => 'sanitize_text_field',
        'transport'         => 'postMessage',
    ) );
    $wp_customize->add_control( 'mytheme_footer_text', array(
        'label'   => 'フッターの文言',
        'section' => 'mytheme_layout',
        'type'    => 'text',
    ) );

    // フッターの文言は「部分更新」でプレビューする(後述)
    $wp_customize->selective_refresh->add_partial( 'mytheme_footer_text', array(
        'selector'        => '.site-footer .footer-text',
        'render_callback' => function () {
            echo esc_html( get_theme_mod( 'mytheme_footer_text', 'My Site' ) );
        },
    ) );
}

// 選択肢に無い値が送られてきたら初期値に戻す
function mytheme_sanitize_select( $input, $setting ) {
    $input   = sanitize_key( $input );
    $choices = $setting->manager->get_control( $setting->id )->choices;

    return array_key_exists( $input, $choices ) ? $input : $setting->default;
}
  • sanitize_callback は、保存する前に値を無害化する関数です。設定ごとに指定します。
  • セレクトボックスの無害化は、コントロールの choices に含まれる値だけを通す形にしています。この例では、設定とコントロールの ID を同じにしているので get_control( $setting->id ) で取り出せます。
  • type には text のほか、textarea、checkbox、radio、select、dropdown-pages、email、url、number などを指定できます。

プレビューの更新方法を選ぶ

設定の transport で、値を変えたときにプレビューをどう更新するかを決めます。

方法 指定 動き 向いているもの
再読み込み 'transport' => 'refresh'(初期値) プレビュー全体を読み込み直す レイアウトの変更など
部分更新 'transport' => 'postMessage' + add_partial() 指定した要素だけ、PHP で描き直して差し替える テキストや HTML の一部
JavaScript 'transport' => 'postMessage' + 自作の JavaScript ページを読み込み直さず、JavaScript で見た目を変える 色や CSS の値

postMessage を指定して部分更新も JavaScript も用意しないと、プレビューは変わりません(保存すれば公開ページには反映されます)。

部分更新

上のコードの add_partial() が部分更新です。selector に一致する要素の中身が、render_callback の出力で置き換わります。テンプレートの側でも同じ要素を出力しておきます。

<p class="footer-text"><?php echo esc_html( get_theme_mod( 'mytheme_footer_text', 'My Site' ) ); ?></p>

部分更新した要素には、プレビュー上に鉛筆のアイコンが付き、クリックすると該当の設定が開きます。

JavaScript で色を変える

プレビューの中で動く JavaScript を、customize_preview_init フックで読み込みます。依存関係に customize-preview を指定します。

<?php
add_action( 'customize_preview_init', function () {
    wp_enqueue_script(
        'mytheme-customizer',
        get_theme_file_uri( 'js/customizer.js' ),
        array( 'customize-preview' ),
        wp_get_theme()->get( 'Version' ),
        true
    );
} );
// js/customizer.js
( function ( api ) {
    api( 'mytheme_primary_color', function ( value ) {
        value.bind( function ( newColor ) {
            // CSS 変数を書き換えると、変数を使っているすべての要素に反映される
            document.documentElement.style.setProperty( '--color-primary', newColor );
        } );
    } );
} )( wp.customize );

公開ページで値を使う

保存した値は get_theme_mod( 設定ID, 初期値 ) で取り出します。2つ目の引数は、まだ保存されていないときに返す値なので、add_setting() の default と同じ値にしておきます。

色は CSS 変数として出力します。テーマの CSS を mytheme-style という名前で読み込んでいる場合の例です。

<?php
add_action( 'wp_enqueue_scripts', function () {
    wp_enqueue_style( 'mytheme-style', get_stylesheet_uri(), array(), wp_get_theme()->get( 'Version' ) );

    $color = sanitize_hex_color( get_theme_mod( 'mytheme_primary_color', '#2271b1' ) );
    if ( $color ) {
        wp_add_inline_style( 'mytheme-style', ':root { --color-primary: ' . $color . '; }' );
    }
} );

テーマの CSS では background-color: var(--color-primary); のように変数を使います。CSS 変数の使い方は CSSカスタムプロパティの記事 で説明しています。

画像とセレクトボックスの値は、テンプレートで次のように使います。

<?php
// バナー画像(添付ファイルの ID から img タグを出力する)
$banner_id = (int) get_theme_mod( 'mytheme_banner', 0 );
if ( $banner_id ) {
    echo wp_get_attachment_image( $banner_id, 'large' );
}

// サイドバーの位置を body のクラスに加える
add_filter( 'body_class', function ( $classes ) {
    $classes[] = 'layout-' . sanitize_html_class( get_theme_mod( 'mytheme_layout', 'sidebar-right' ) );
    return $classes;
} );

body_class フィルターは functions.php に、バナーの部分はテンプレート(header.php など)に書きます。

確かめる

  1. 「外観」→「カスタマイズ」を開き、「テーマ設定」のパネルと2つのセクションが出ているか確かめます。
  2. 色を変えて、プレビューが読み込み直されずに変わるか、フッターの文言を変えて、その部分だけが変わるかを確かめます。
  3. 「公開」を押したあと、ログアウトした状態で公開ページを開き、値が反映されているか確かめます。

まとめ

  • customize_register フックで、パネル・セクション・設定・コントロールを追加します。コールバックは1つにまとめます。
  • 設定ごとに sanitize_callback を指定し、選択肢は choices にある値だけを通します。
  • postMessage を使う場合は、部分更新(add_partial())か、customize_preview_init で読み込む JavaScript を用意します。
  • 値は get_theme_mod() で取り出し、色は wp_add_inline_style() で CSS 変数として出力します。
  • ブロックテーマでは、カスタマイザーではなくサイトエディターと theme.json が設定の中心です。

お気軽にご相談ください

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