テーマカスタマイザーの設定項目を2つ以上使用するライブプレビュー編集

毎回更新したい人には無関係の話ですが、簡単なスタイル修正程度ならjQUeryで簡単に編集できますし、何よりライブプレビューの方が素早く仕上がりを確認できます。
ただ、最近まで僕も編集するのを忘れていたんですが、テーマカスタマイザーの設定によってはちょっと複雑なライブプレビューが必要な場合がありますよね。「〜〜モードはこういう処理」といった感じで、テーマカスタマイザーの別の設定項目によって、処理の仕方が異なる設定項目だって存在します。
基本的なライブプレビューの実装方法をまだ知らないという方は、先に「テーマカスタマイザーでの編集をライブプレビューする方法」をご参照ください。
複雑な編集が必要な場合
複雑な設定変更の場合、何が問題になるかですが、設定変更時に「wp.customize」で取得できるデータが「newval」だけということです。
例えば、「設定1」で「リストアイテムの横幅を全て均等にする」もしくは「各リストアイテムの横幅をアイテム内のコンテンツに合わせる(バラバラ)」の2択にし、「設定2」で「均等にする場合の横幅の大きさを指定する」とします。この場合「設定1」の値を変更する際、ライブプレビューの処理をする際「設定2」のデータが必要になり、当然「設定2」の値を変更する際も「設定1」のデータが必要になります。
つまり、課題はテーマカスタマイザーで設定変更した後の設定値をどのようにして取得するかとなります。
解決方法
実は解決方法は非常にシンプルです。
ワードプレスに備わっている関数「get_theme_mods」で全てのテーマカスタマイザーでの設定値を配列で取得し、これをJSON形式にしてしまいます。あとはグローバル変数にして、値を取得、設定後に変更すればいいだけです。
要約するとこんな感じです。
- 「get_theme_mods」からJSONを作成
- JavaScriptで変数をグローバル化
- wp.customizeの処理時に値を「取得・変更」処理
という操作を行います。
「get_theme_mods」からJSONを作成
コードは非常にシンプルです。「get_theme_mods」で取得した配列を使用します。
方法は2種類あり、使いやすい方法を選択してください。
1つは直接scriptタグを使って定義し、もう1つはワードプレス関数「wp_localize_script」を使用する方法です。
前者は以下のように書きます。
if( is_customize_preview() ) { // 「customize_preview_init」にフック add_action( 'customize_preview_init', 'theme_customizer_live_preview_js' ); // 出力する関数の定義 function theme_customizer_live_preview_js() { // JSON形式のStringを取得 $theme_mods_json = json_encode( get_theme_mods() ); // 直接scriptタグでJavaScriptの変数「themeModsJSON」を定義するコードを出力 echo '<script>var themeModsJSON = ' . $theme_mods_json . ';</script>'; // プレビュー用のJSファイルの出力 wp_enqueue_script( 'your_theme_customizer_js', get_template_directory_uri() . '/path-to-your/theme-customizer.js', array( 'jquery', 'customize-preview' ), // 「jquery」と「customize-preview」に依存 '', true ); } }
後者は以下のように書きます。
if( is_customize_preview() ) { // 「customize_preview_init」にフック add_action( 'customize_preview_init', 'theme_customizer_live_preview_js' ); // 出力する関数の定義 function theme_customizer_live_preview_js() { // テーマカスタマイザーの設定値を取得 $theme_mods = get_theme_mods(); // JSファイルを登録(出力はまだ) wp_register_script( 'your_theme_customizer_js', get_template_directory_uri() . '/path-to-your/theme-customizer.js', array( 'jquery', 'customize-preview' ), // 「jquery」と「customize-preview」に依存 '', true ); // 「登録したJSファイルのハンドル」「定義するJSの変数名」「JSの変数にJSON形式で格納したいPHPの変数」 wp_localize_script( 'your_theme_customizer_js', 'themeModsJSON', $theme_mods ); // JSファイルの出力 wp_enqueue_script( 'your_theme_customizer_js' ); } }
前者は出力される場所を把握してJSファイルが出力されるよりも前に定義しなくちゃいけませんが、後者はハンドルを指定することで変数を使用したいJSファイルの前に定義してくれますのでより確実です。
また、後者で使用しているワードプレス関数「wp_localize_script」の3つ目の値として使用している変数は、JSON形式のStringではなく配列のままです。「wp_localize_script」がJSON形式のStringに自動変換してくれますので、前者と混同しないようにしましょう。
JavaScriptで変数をグローバル化
上の方法でJSファイル内で「themeModsJSON」が使用できるようになりましたが、まだ課題は残っています。
「wp.customize」内での処理に使用するためにグローバル化することです。
これは1行で足りますので、JSファイルの冒頭に書き足して下さい。
window.themeModsJSON = themeModsJSON;
JavaScriptのグローバル変数は、「window」に格納することで定義できますので、「window.variableName = variableName;」と定義しておくだけでグローバル化できます。
これで「window.variableName」を使うことで、「wp.customize」内でもテーマカスタマイザーでの値を取得できるようになりました。
「wp.customize」での処理時に値を「取得・変更」処理
グローバル化した変数は「グローバル変数.設定ID」が各設定項目の設定値となっていますので、これを操作してライブプレビューの処理をこなしていきます。
JSファイルには以下のように書いていきます。
( function( $ ) { // グローバル化 window.themeModsJSON = themeModsJSON; wp.customize( 'your_setting_id', function( value ) { value.bind( function( newval ) { // 他の設定項目での処理でも使用できるように、設定後の値に変更 window.themeModsJSON.your_setting_id = newval; // 設定項目に応じた処理 if( window.themeModsJSON.your_setting_id_condition == 'some-values' ) { // 設定項目id「your_setting_id_condition」の設定値が「some-values」の場合の処理 } else if( window.themeModsJSON.your_setting_id_condition == 'any-values' ) { // 設定項目id「your_setting_id_condition」の設定値が「any-values」の場合の処理 } else { // 設定項目id「your_setting_id_condition」の設定値がその他の場合の処理 } }); }); // その他の設定 /* wp.customize( 'your_setting_id_condition', ....... */ } ) ( jQuery );
といった感じです。
あとは、他の設定項目でもちゃんと設定変更の時にグローバル変数の値を設定後の値に変更しておけば、自由に柔軟なライブプレビューが可能になります。