テンプレート作成の手順を徐々に公開しつつ、その中で
WordPressのバグについて触れていこうと思っていたのですが、
順に記事を書いていくと、そこに到達するのは
かなり先の話になりそうなので、先に紹介します。
他の記事でも多々言及しているのですが、
「WordPress Codex」 や 「WordPress Codex 日本語版」
に従ってプログラムを書いているはずにも関わらず、
「ぬ?」と思うような(WordPress 本体の)バグにあたります。
今回はカスタムヘッダーを利用する際に、
JavaScriptエラーを発するバグを紹介します。
( 解説に使用している WordPress ソースコードは WordPress 3.9 です )
【バグ確認バージョン】
WordPress 3.9
WordPress 3.9.1
(もしかしたら 3.8 でも出ているかもしれません)
【前提条件】
add_theme_support 関数の第一パラメータに ‘custom-header’ を指定して
カスタムヘッダーを利用する指定をした際、デフォルトの挙動を指定する
第二パラメータの連想配列の ‘default-text-color’ が未指定の場合
【現象】
管理画面[外観 - ヘッダー] にて
文字色選択ピッカーが表示されず(なぜかタイトルだけは出る)、
「ヘッダーのテキスト」の項目で「ヘッダー画像上にテキストを表示する」
のチェックを OFF から ON にすると JavaScript エラーが発生する
【解消方法】
add_theme_support 関数の第一パラメータに ‘custom-header’ を指定する際、
デフォルトの挙動を指定する第二パラメータの連想配列の
‘default-text-color’ は必ず有効な色コードを指定する
管理画面からヘッダー画像を変更したり、ブログタイトルや
紹介文の文字色を変更できるようにさせるためには、
add_theme_support 関数の
第一パラメータに ‘custom-header’ を、
第二パラメータにデフォルトの挙動を指定する連想配列を与え、
カスタムヘッダーのサポートを有効にします。
/* カスタムヘッダー パラメータを指定して追加 */ add_theme_support('custom-header', array( 'default-image' => get_template_directory_uri() . '/images/header_photo-green.jpg', // デフォルトヘッダー画像 'random-default' => false, // ヘッダー画像をランダム表示するか 'width' => 986, // ヘッダー画像幅 'height' => 150, // ヘッダー画像高 'flex-width' => false, // 画像幅をフレキシブルにするか ・・・true:指定サイズに関係なくトリミング可能 / false:指定サイズに準拠した割合でのみトリミング可能 'flex-height' => false, // 画像高をフレキシブルにするか ・・・true:指定サイズに関係なくトリミング可能 / false:指定サイズに準拠した割合でのみトリミング可能 'default-text-color' => '', // ヘッダーテキスト文字色 'header-text' => true, // ヘッダーテキストの表示制御可否 'uploads' => true, // ヘッダー画像アップロード可否 'wp-head-callback' => 'header_style', // ユーザ画面ヘッダーで、管理画面でのカスタマイズスタイルを適用するためのコールバック 'admin-head-callback' => 'admin_header_style', // 管理画面で、[外観 - カスタマイズ]をプレビューするためのコールバック 'admin-preview-callback' => 'admin_header_preview' // 管理画面で、[外観 - ヘッダー]をプレビューするためのコールバック ));
上記のように、‘default-text-color’ を空白にしたり、
配列上欠落させたりすると、「 管理画面[外観 - ヘッダー] 」 でJavaScriptエラーが
発生します。
なぜこんなことになるのでしょう?
if ( current_theme_supports( 'custom-header', 'default-text-color' ) ) {
$default_color = '#' . get_theme_support( 'custom-header', 'default-text-color' );
$default_color_attr = ' data-default-color="' . esc_attr( $default_color ) . '"';
echo '';
if ( $default_color )
echo '
';
}/wp-admin/custom-header.php の 630行目から638行目で、
‘default-text-color’ の値の有無を見て、文字色の選択をさせるピッカーを
表示させるかどうかの制御をしています。
‘default-text-color’ の中身がないと、ピッカーを構成する TextBox 等が
表示されません。
(ですが、タイトルはこの表示制御ブロックに入ってなく、必ず表示される不思議仕様)
<script type="text/javascript"> /* <![CDATA[ */ (function($){ var default_color = '#<?php echo get_theme_support( 'custom-header', 'default-text-color' ); ?>', header_text_fields; function pickColor(color) { $('#name').css('color', color); $('#desc').css('color', color); $('#text-color').val(color); } function toggle_text() { var checked = $('#display-header-text').prop('checked'), text_color; header_text_fields.toggle( checked ); if ( ! checked ) return; text_color = $('#text-color'); if ( '' == text_color.val().replace('#', '') ) { text_color.val( default_color ); pickColor( default_color ); } else { pickColor( text_color.val() ); } } $(document).ready(function() { var text_color = $('#text-color'); header_text_fields = $('.displaying-header-text'); text_color.wpColorPicker({ change: function( event, ui ) { pickColor( text_color.wpColorPicker('color') ); }, clear: function() { pickColor( '' ); } }); $('#display-header-text').click( toggle_text ); <?php if ( ! display_header_text() ) : ?> toggle_text(); <?php endif; ?> }); })(jQuery); /* ]]> */ </script>
一方、 /wp-admin/custom-header.php の 329行目から374行目で出力される
JavaScript関数(jQuery を利用) では、ピッカーで選択されている色で、
ブログタイトルや紹介文の文字色制御を行っています。
実際に JavaScript エラーを吐いているのは、このブロック内の、348行目です。
この JavaScript関数は、ピッカーで色選択された時だけでなく、
「ヘッダー画像上にテキストを表示する」 のチェックを OFF から ON にした際にも
実行されるよう、イベントに関連付けされています。
‘default-text-color’ の値が設定されていない場合、
ピッカーのTextBoxは表示されていませんから、
HTML上表示されていない(存在しない)TextBoxから値を取得しようとすると
エラーになるのは当たり前ですね。
WordPress本体のソースを修正した場合、アップデートで上書きされてしまいますし、
このJavaScript関数は、関数名が与えられていない即時関数ですので、
オーバーライド(のように)して関数の動作を上書きしてやることもできません。
不本意ながら、解消方法としては、’default-text-color’ に
必ず色コードとして有効な値を設定してやるのが一番よさそうな手段です。
本当は、「CSSでブログタイトルと紹介文の色は別々のものを設定しておき、
管理画面から指定された時だけ双方指定された色で表示する」 といった
ふうにさせたかったのですが・・・