Theme Customization API をそのまま使うと冗長で辛くなってきたのでもっと楽できるクラスを作った話

この記事は Habakiri Advent Calendar 2015 6日目の記事です。

これまでのアドベントカレンダーで、Habakiri はカスタマイザーで色々できますよ、ということを何度か書きました。色々できるということは、内部的にはコード量が多くなってしまい、どうしても煩雑になってきてしまうのですが、その辺りをどうやって簡素化しようとしたかを書きたいと思います。

Theme Customization API

カスタマイザーは Theme Customization API というものを使って実装していきます。基本的な使い方は Codex に詳しく書いてあるので、その通りに進めていけば普通に実装できると思います。Theme Customization API は次のような流れで実装していきます。

/**
 * テーマ設定(セッティング)の追加
 *
 * 下記は「ヘッダーのテキスト色」のための設定を追加している。
 */
$wp_customize->add_setting( 'header_textcolor' , array(
    'default'           => '#000000',
    'sanitize_callback' => 'sanitize_hex_color'
) );

/**
 * セクションの追加
 *
 * セクションは、カスタマイザーの管理画面に表示する「枠」を定義するもの。
 * 実際の入力フォームは add_control で追加する。
 */
$wp_customize->add_section( 'header_textcolor' , array(
   'title' => __( 'Visible Section Name', 'mytheme' ),
   'priority' => 30,
) );

/**
 * コントロール(入力フォームの追加)
 *
 * セクションを追加しただけでは入力フォームは表示されません。
 * このメソッドで何(セッティング)の入力フォームをどこ(セクション)に追加するかを設定。
 */
$wp_customize->add_control(
    new WP_Customize_Color_Control(
        $wp_customize,
        'header_textcolor',
        array(
            'label'    => __( 'Header Color', 'mytheme' ),
            'section'  => 'header_textcolor',
            'settings' => 'header_textcolor',
        )
    )
);

/**
 * CSS を出力
 */
function mytheme_customize_css() {
    ?>
    <style type="text/css">
    h1 {
        color: <?php echo get_theme_mod( 'header_color', '#000000' ); ?>;
    }
    </style>
    <?php
}
add_action( 'wp_head', 'mytheme_customize_css' );

以上が、カスタマイザーに「ヘッダーのテキスト色」の設定を追加するコードです。皆さん、こう思ったことでしょう。「なげぇ…」

Habakiri は色の設定だけでも30個弱、そのほかにもレイアウトの設定やスライドショーの設定など数多くの設定項目があります。はじめは上記のコードをコピペしてせっせと追加していたのですが、普通はセッティングとコントロールは1対1なのにわざわざ2つに分けて書くのは面倒とか、同じようなコードを何度も何度も書くのがめんどくさくなってきました。

そこで、もっと簡単にカスタマイザーに項目を追加できるようにクラスを作りました。

Habakiri Customizer Framework

前述した「ヘッダーのテキスト色」の設定の追加が、Habakiri Customizer Framework を使えば下記のように書けます。

$this->Customizer_Framework->add_section( 'header_textcolor', array(
    'title'    =>  __( 'Visible Section Name', 'mytheme' ),
    'priority' => 30,
) );

$this->Customizer_Framework->color( 'header_textcolor', array(
    'label'   => __( 'Header Color', 'mytheme' ),
    'default' => '#000000',
    'section' => 'header_textcolor',
) );

$this->Customizer_Framework->register_styles(
    'h1',
        sprintf( 'color: %s', get_theme_mod( 'header_color', '#000000' ) )
    );
);

どうでしょう、簡単になった感じしますかね。add_settingadd_controleを統合し、また、表示したい入力フォームを直接メソッドで呼び出すようにしました。上記の例でいうと、カラッピッカーを表示したいので$this->Customizer_Framework->colorを使っている、という部分ですね。どのような入力フォームが使用できるかは「Habakiri Customizer Framework – GitHub」を見ていただければわかると思います。

Customization API のマニュアルにはあんまり詳しく項目の種類や属性の指定方法が書かれていないので、ちょっと詳しくやろうとするとコアのコードを読む必要が出てきます。それに比べると Habakiri Customizer Framework のコードを見てフォームを把握するのはずいぶん楽かなと…。

サニタイズ処理

デフォルトの Customization API でもう一つ面倒だったのかサニタイズ処理です。セキュリティ上問題があるような値が入力されたときは無害化して出力する、というやつですね。どのようなサニタイズ処理をするかはadd_settingの引数でsanitize_callbackとして指定するわけですが、2点問題があります。

  • 基本的に、入力フォームによってどのようなサニタイズをするかは特定されるのに、いちいち毎回指定しないといけない
  • 選択肢フォーム(セレクト、ラジオ、チェックボックス)と数値フォームのサニタイズ関数が存在しない

例えば、カラーピッカーのサニタイズであれば必ずsanitize_hex_colorなわけですが、色の設定が30個ある場合はその30個で毎回sanitize_hex_colorを指定しなければいけなくて無駄です。なので、Habakiri Customizer Framework では$this->Customizer_Framework->colorとしてカラーピッカーを使う場合は自動的にカラーコードの用のサニタイズが走るようにしました。

また、選択肢フォーム(セレクト、ラジオ、チェックボックス)と数値フォームに対するサニタイズはデフォルトでは存在しないようだったので、選択肢フォームの場合は指定した選択肢以外が保存されている場合は出力しないように、数値フォームの場合は数値以外が保存されている場合は出力しないように処理を加えました。

出力される CSS について

CSS の出力も関数を通して空白や改行を削除するようにしています。削除にかかる処理の時間と非圧縮の CSS を出力することのどちらのほうが時間がかかるのか、すごく微妙だと思いますが、ソースを表示したときのスッキリ感が精神衛生上良かったのでそのようにしています。

余談

もともとの Customization API は、拡張性を高めるためにわざと冗長な記述をするようになっているのだと思いますが、普通に使う分には面倒でしかないので、上記のように自分でラップするクラスを作ったほうがコード量が減って幸せになると思います。ちなみに Habakiri Customizer Framework は Habakiri 以外のテーマに組み込んで使用できるので、気になる方は試されてみてください。

この投稿へのコメント

コメントはありません。

コメントを残す

この投稿へのトラックバック

  1. […] タマイザーで色々できますよ、ということを何度か書きました。 [紹介元] Theme Customization API をそのまま使うと冗長で辛くなってきたのでもっと楽できるクラスを作った話 – Habakiri […]

トラックバック URL