WordPress 4.1から title 要素の作り方が変わるという話
映画『インターステラー』を主に TARS 目当てに観てきた kagata です。『キカイダーREBOOT』といい『her/世界でひとつの彼女』といい、今年はロボットや人工知能の出てくる映画が印象に残っています。年末公開の『ベイマックス』も期待。
さて、WordPress の次期バージョン4.1が今月リリースを目指して準備されています。そのバージョン4.1から、title 要素の自動生成という新しい機能が盛り込まれる予定です。バシャログ読者に多いであろうフロントエンド畑の方々や、WordPress テーマカスタマイズの初心者のみなさまにもかかわりがありそうということで、ちょっと調べてみました。
おさらい:これまでの WordPress での title 要素
これまで、WordPress での title 要素はテーマの header.php にテンプレート関数 wp_title()
を使って作ることがほとんどでした。
例えば、WordPress 4.0.1のデフォルトテーマ “Twenty Fourteen” の header.php はこんな感じ。
<title><?php wp_title( '|', true, 'right' ); ?></title>
出力される HTML はこう。
<title>記事のタイトル|サイトの名前</title>
追記その1:title 要素にサイト名が含まれる理由(テーマ "Twenty Fourteen" の場合)
この記事を公開してすぐ、wp_title()
の出力にサイト名を含めるカスタマイズの説明をするのを忘れていることに気づきました…。
wp_title()
はデフォルトでは出力にサイト名を含みません。テーマ "Twenty Fourteen" がこのような挙動を示すのは、functions.php にある次の処理によるものです。
function twentyfourteen_wp_title( $title, $sep ) {
global $paged, $page;
if ( is_feed() ) {
return $title;
}
// Add the site name.
$title .= get_bloginfo( 'name', 'display' );
// Add the site description for the home/front page.
$site_description = get_bloginfo( 'description', 'display' );
if ( $site_description && ( is_home() || is_front_page() ) ) {
$title = "$title $sep $site_description";
}
// Add a page number if necessary.
if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) {
$title = "$title $sep " . sprintf( __( 'Page %s', 'twentyfourteen' ), max( $paged, $page ) );
}
return $title;
}
add_filter( 'wp_title', 'twentyfourteen_wp_title', 10, 2 );
フィルターフック wp_title
に独自の処理が引っかけられているのがわかりますね。
自動生成機能を使う方法
WordPress 4.1からは、上のようにテンプレートファイルに title 要素を直接書かなくてよくなります。その代わりに、テーマの functions.php に次のように書きます。
function my_setup_theme() {
add_theme_support( 'title-tag' );
}
add_action( 'after_setup_theme', 'my_setup_theme' );
すると、header.php に記述している wp_head()
がほかのいろんなものといっしょに title 要素も出力してくれます。こんな感じで。
<title>記事のタイトル | サイトの名前</title>
WordPress 4.1に同梱される新しいデフォルトテーマ “Twenty Fifteen” でも、同様の方法で title 要素が組み込まれています。
どうなってるの
WordPress 4.1はどのような仕組みで title 要素を出力しているのか、バージョン4.1ベータ2のコードをもとにロジックを追ってみることにしました。
まずは title 要素を直接出力している関数 wp_head()
の中身を見てみました。
function wp_head() {
/**
* Print scripts or data in the head tag on the front end.
*
* @since 1.5.0
*/
do_action( 'wp_head' );
}
…ああ、中身はアクションフックだけだったんですね…知らなかった。
とすると、アクションフック wp_head
にデフォルトのアクションを引っかける処理がコアのどこかにあるはず。探してみたところ、wp-includes/default-filters.php にありました。
バージョン4.0.1と4.1でこのファイルの差分をとってみると、次の記述が追加されていました。’_wp_render_title_tag’ という関数名からして title 要素の出力に関係がありそうです。
add_action( 'wp_head', '_wp_render_title_tag', 1 );
そして、同じく4.1で追加された関数 _wp_render_title_tag()
の中身は次のとおり。
function _wp_render_title_tag() {
if ( ! current_theme_supports( 'title-tag' ) ) {
return;
}
// This can only work internally on wp_head.
if ( ! did_action( 'wp_head' ) && ! doing_action( 'wp_head' ) ) {
return;
}
echo '<title>' . wp_title( '|', false, 'right' ) . "</title>\n";
}
処理の本質は最後の echo 文ですね。ここで、おなじみの関数 wp_title()
が使われています。引数を見れば、title 要素としてどんな内容が出力されるかも見当がつきますね。
追記その2:title 要素にサイト名が含まれる理由(自動生成の場合)
上記で説明したテーマ "Twenty Fourteen" の場合と同様、この自動生成機能においても title 要素にサイト名が入ります。これはテーマ側のカスタマイズではなくコアの機能として実現されているものです。
バージョン4.0.1とバージョン4.1ベータ2で関数 wp_title()
の差分をとると、次の処理が追加されていることがわかります。
if ( current_theme_supports( 'title-tag' ) && ! is_feed() ) {
$title .= get_bloginfo( 'name', 'display' );
$site_description = get_bloginfo( 'description', 'display' );
if ( $site_description && ( is_home() || is_front_page() ) ) {
$title .= " $sep $site_description";
}
if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) {
$title .= " $sep " . sprintf( __( 'Page %s' ), max( $paged, $page ) );
}
}
add_theme_support( 'title-tag' )
で自動生成機能を有効にすると、wp_title()
の出力にサイト名(やサイトの説明)が自動で追加されるんですね。逆に自動生成機能を使わず header.php に wp_title()
を直接書けば、従来どおりサイト名は出力に含まれないこともわかります。
自動生成のメリット、そして後方互換
この新しい仕組みは主にプラグインで title 要素の出力をカスタマイズする際にメリットとなりそうです。従来はフィルターフック wp_title
でゴニョゴニョするしかなかったのが、remove_action( 'wp_head', '_wp_render_title_tag' )
して add_action( 'wp_head', 'my_render_title_tag' )
して関数 my_render_title_tag()
を書く…という方法も使えるようになります。複雑なカスタマイズをするには、こちらの方が便利そうですね。
一方で、HTML は書くけど PHP はちょっと…という人には、またよくわからないおまじないが増えてしまった感があるかもしれません。いちおう add_theme_support( 'title-tag' )
を functions.php に書かない限り title 要素は自動生成されないので、従来どおり header.php に title 要素を直接書くやり方をとることも引き続きできます。また、WordPress を4.1 にアップデートしたからといって、自分が過去に作ったテーマに title 要素が自動生成されてだぶってしまうということもありません。
ただ、今後この新しい仕組みに対応したプラグインが出てくると、古い書き方のテーマでは動作しないということもあるかもしれません。テーマ作成側も早いうちに対応してしまうのが吉でしょう。