2026年5月20日
2026年5月20日
WordPressのカスタマイザーAPIでリアルタイムプレビューを実装する方法
はじめに
WordPressのカスタマイザー(外観→カスタマイズ)は customize_register フックと WP_Customize_Manager を使って拡張できます。postMessage 転送を使うと、設定変更がリアルタイムでプレビューに反映される快適な編集体験を提供できます。
症状・原因
- カスタマイザーにオリジナルの設定項目を追加したい
- 設定を変更するとリアルタイムでプレビューに反映させたい
- カラーピッカー・画像アップロード・テキストなどの入力コントロールを使いたい
- カスタマイザーのセクションを整理してグループ化したい
解決手順
ステップ1:カスタマイザーにパネルとセクションを追加する
// functions.php
function mytheme_customize_register(WP_Customize_Manager $wp_customize): void {
// パネルを追加(複数セクションをまとめる)
$wp_customize->add_panel('mytheme_panel', [
'title' => 'テーマ設定',
'description' => 'テーマの外観設定',
'priority' => 130,
]);
// セクションを追加
$wp_customize->add_section('mytheme_colors', [
'title' => 'カラー設定',
'panel' => 'mytheme_panel',
'priority' => 10,
]);
$wp_customize->add_section('mytheme_footer', [
'title' => 'フッター設定',
'panel' => 'mytheme_panel',
'priority' => 20,
]);
}
add_action('customize_register', 'mytheme_customize_register');
ステップ2:設定とコントロールを追加する
// functions.php(customize_registerコールバック内に追記)
function mytheme_customize_register(WP_Customize_Manager $wp_customize): void {
// === カラーピッカー ===
$wp_customize->add_setting('mytheme_primary_color', [
'default' => '#2271b1',
'sanitize_callback' => 'sanitize_hex_color',
'transport' => 'postMessage', // リアルタイム転送
]);
$wp_customize->add_control(new WP_Customize_Color_Control(
$wp_customize,
'mytheme_primary_color',
[
'label' => 'メインカラー',
'section' => 'mytheme_colors',
]
));
// === テキスト入力 ===
$wp_customize->add_setting('mytheme_footer_text', [
'default' => '© ' . date('Y') . ' My Site',
'sanitize_callback' => 'sanitize_text_field',
'transport' => 'postMessage',
]);
$wp_customize->add_control('mytheme_footer_text', [
'label' => 'フッターテキスト',
'section' => 'mytheme_footer',
'type' => 'text',
'input_attrs' => ['placeholder' => 'コピーライト文を入力'],
]);
// === 画像アップロード ===
$wp_customize->add_setting('mytheme_logo', [
'default' => '',
'sanitize_callback' => 'absint', // 添付ファイルIDを整数でサニタイズ
'transport' => 'refresh',
]);
$wp_customize->add_control(new WP_Customize_Media_Control(
$wp_customize,
'mytheme_logo',
[
'label' => 'ロゴ画像',
'section' => 'mytheme_colors',
'mime_type' => 'image',
]
));
// === セレクトボックス ===
$wp_customize->add_setting('mytheme_layout', [
'default' => 'sidebar-right',
'sanitize_callback' => 'mytheme_sanitize_select',
]);
$wp_customize->add_control('mytheme_layout', [
'label' => 'レイアウト',
'section' => 'mytheme_footer',
'type' => 'select',
'choices' => [
'sidebar-right' => '右サイドバー',
'sidebar-left' => '左サイドバー',
'no-sidebar' => 'サイドバーなし',
],
]);
}
add_action('customize_register', 'mytheme_customize_register');
function mytheme_sanitize_select(string $value, WP_Customize_Setting $setting): string {
$choices = $setting->manager->get_control($setting->id)->choices;
return array_key_exists($value, $choices) ? $value : $setting->default;
}
ステップ3:postMessageでリアルタイムプレビューを実装する
// js/customizer.js: カスタマイザーのJSプレビュー制御
(function ($) {
'use strict';
// メインカラーをリアルタイムで反映
wp.customize('mytheme_primary_color', function (value) {
value.bind(function (newColor) {
// CSS変数を更新
document.documentElement.style.setProperty('--color-primary', newColor);
// 直接スタイルを変更する場合
$('.site-header').css('background-color', newColor);
});
});
// フッターテキストをリアルタイムで反映
wp.customize('mytheme_footer_text', function (value) {
value.bind(function (newText) {
$('.site-footer .footer-text').text(newText);
});
});
}(jQuery));
// functions.php: カスタマイザーJSをエンキュー
function mytheme_customize_preview_js(): void {
wp_enqueue_script(
'mytheme-customizer',
get_template_directory_uri() . '/js/customizer.js',
['customize-preview', 'jquery'],
wp_get_theme()->get('Version'),
true
);
}
add_action('customize_preview_init', 'mytheme_customize_preview_js');
ステップ4:設定値をテンプレートで出力する
// functions.php
function mytheme_customize_css(): void {
$primary_color = get_theme_mod('mytheme_primary_color', '#2271b1');
?>
<style id="mytheme-customizer-css">
:root {
--color-primary: <?php echo esc_attr($primary_color); ?>;
}
.site-header { background-color: <?php echo esc_attr($primary_color); ?>; }
</style>
<?php
}
add_action('wp_head', 'mytheme_customize_css');
// テンプレート内でのテキスト取得
$footer_text = get_theme_mod('mytheme_footer_text', '© ' . date('Y') . ' My Site');
echo wp_kses_post($footer_text);
注意事項
transport => 'postMessage'を指定した設定は、必ずJavaScriptでプレビュー更新を実装してください。JSがないと変更が反映されませんtransport => 'refresh'はページ全体をリロードしてプレビューを更新します。画像やレイアウト変更など、JSでは難しい変更に使いますget_theme_mod()はカスタマイザーの設定値を取得します。get_option()とは異なり、デフォルト値を第2引数で指定できます
まとめ
customize_register フックで add_panel・add_section・add_setting・add_control を組み合わせてカスタマイザーを拡張します。transport: postMessage + customize_preview_init のJSで即時反映を実現し、テンプレートでは get_theme_mod() で値を取得して wp_head でCSSに出力します。