テーマを HTML5 にしてみた!けれど…
<!DOCTYPE html>
から始まって <section>
<article>
を駆使して HTML5でテーマを作った!と思ったら、
wp_enqueue_style()
して出力されるlink
タグにtype="text/css"
がついていたりwp_enqueue_script()
して出力されるscript
タグにtype="text/javascript"
がついていて
げんなりしてしまったこと、ありませんか? 私はあります。デフォルトのタイプ属性として定義済だから省略できるわけで、あっても間違いではないのですが、HTML ソースがシンプルになって気持ちがいいのも HTML5 の効果だとすれば、無くてもいいものは無い方がいいですね。
それじゃぁ、と header.php に直接タグを書こうとすると「それは違うよね」とどこからか声が聞こえてきます…
こんなときは WordPress カスタマイズ虎の巻 をひも解いてみましょう。
その壱 フィルターで書き換えるべし
スタイルの方は style_loader_tag
というフィルターフックで link
タグを書き換えることができます。
preg_replace( array( "| type='.+?'\s*|", '| />|' ), array( ' ', '>' ), $tag );
こんな感じで良さそうです。type 属性を削除するついでに />
(これは何と呼ぶんでしょうか…)を >
に置換しています。HTML5 的には />
でも良いのですが、無くてもいいものは無い方がいいルールに従ってシンプルに徹します。
一方、スクリプトの方は style_loader_tag
に相当するフィルターが無く、タグがいきなり echo
されています。困りましたね… WordPress カスタマイズ虎の巻 を読み進めましょう。
その弐 クラスを継承すべし
スクリプト関連の処理は WP_Scripts クラスが担っていて、必要になったときにこれを new
したインスタンスがグローバル変数の $wp_scripts
に代入されます。ということは、WP_Scripts クラスを継承して処理を書き換えてグローバル変数の $wp_scripts
に突っ込めば、こちらの思うがままということになります。というわけで継承してみました。
継承ついでに header.php に html5.js の条件付きコメントを直書きしなくて済むようにしておきました。
スクリプトで条件付きコメントを使う
wp_enqueue_style()
したスタイルは条件付きコメントで囲って link
タグを出力することができます。wp_enqueue_styles
アクションをフックして、
wp_enqueue_style( 'ie7', get_stylesheet_directory_uri() . '/css/ie7.css' ); $GLOBALS['wp_styles']->add_data( 'ie7', 'conditional', 'lte IE 7' );
とすれば、HTML ソースに、
<!--[if lte IE 7]> <link rel='stylesheet' href='http://example.com/wp-content/themes/mytheme/css/ie7.css?ver=3.5' media='all'> <![endif]-->
のように出力されます。どちらかというとスクリプトの方が需要がある気がしますが、WordPress はスタイルしかサポートしていないため、上記の PM_Scripts クラスで実装しました。wp_enqueue_scripts
アクションをフックして、
wp_enqueue_script( 'html5', get_stylesheet_directory_uri() . '/js/html5.js' ); $GLOBALS['wp_scripts']->add_data( 'html5', 'conditional', 'lt IE 9' );
とすれば、HTML ソースに、
<!--[if lt IE 9]> <script src='http://example.com/wp-content/themes/mythemes/js/html5.js?ver=3.5'></script> <![endif]-->
のように出力されます。
IE のためだけの対応をしなくてよい未来は、もうすぐやってきますよ…きっと…
add_data() 豆知識
使う機会はあまりありませんが WP_Styles, WP_Scripts クラスの add_data()
メソッドでいろいろなことができます。
$GLOBALS['wp_styles']->add_data( 'スタイルのID', 'alt', true ); -----> link タグの rel 属性を rel='alternate stylesheet' にします
$GLOBALS['wp_styles']->add_data( 'スタイルのID', 'title', 'タイトルですよ' ); -----> link タグに title='タイトルですよ' を追加します
$GLOBALS['wp_scripts']->add_data( 'スクリプトのID', 'data', 'JavaScript のコード' ); -----> script タグの前にインラインでスクリプトを出力します。
wp_localize_script() 豆知識
話題がどんどんそれてますが、Ajax でポストするデータを PHP から JavaScript に渡すときに良く使う関数を紹介します。本来は wp_localize_script() の名のとおり、スクリプト内で使うテキストをローカライズするためのものだと思われます。なお、この関数は対象とするスクリプトを enqueue した後で呼ぶ必要があります。以下のように書くと、
wp_enqueue_script( 'my_script', get_stylesheet_directory_uri() . '/js/my_script.js' ); $params = array( 'action' => 'my_action' , '_ajax_nonce' => wp_create_nonce( 'my_action' ) , 'post_id' => $post->ID ); wp_localize_script( 'my_script', 'my_var', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) , 'params' => $params ) );
HTML ソースには以下のように出力されます。
<!-- var my_var = { json_encode() された変数の値 }; //-->
インラインの方は HTML5 ぽく CDATA
を無くしてあります。これで my_script.js 内の JavaScript から my_var.ajaxurl
my_var.params.action
などの値を使うことができますね。
まとめ
style_loader_tag
フィルターと PM_Scripts クラスの使い方は以下のとおり。ここでは link
タグに付く ID も消しています。
WP_Styles, WP_Scripts, enqueue 関連は concat
(enqueue された内容を連結して出力)の仕組みもあったりと、結構奥の深いつくりになっていますよ。ぜひコードを読んでみてください。
また、今回のクラスを継承してカスタマイズする方法は、適切なフックがない場合に有効なケースが多いです。覚えておいて損はないですよ。
ではまた。