WordPress:wp_head()でのtitleタグ出力有効化と内容変更

wp_head()はscriptやstyleなどのhead内に配置する情報を生成してくれる。
以前はtitleタグの生成をしてくれなかったが、WordPress4.4以降からできるようになっている。
これによりheader.phpなどのテンプレートを修正しなくても、titleタグの内容を変更できるようになった。

しかしtitleタグの生成はデフォルトでは無効となっているため、有効化する必要がある。
ただし形式が固定のため、フィルターを活用して出力するtitleタグの内容を変更する必要がある。

titleタグ出力有効化

デフォルトでは、wp_head()はtitleタグ出力しない。
そこで、次の関数をfunctions.phpなどに記述する。

  • add_theme_support( 'title-tag' );
AFFS Simple Code Viewer
Copy

すると、次のようなタグを出力してくれる。

出力例

■TOPページ
<title>My Blog &#8211; My WordPress Blog</title>
「サイトのタイトル - キャッチフレーズ」が出力されます。

■投稿ページ
<title>Hello world! &#8211; My Blog</title>
「投稿のタイトル - サイトのタイトル - キャッチフレーズ」が出力されます。

■内部動作的な話

wp-includes/default-filters.phpを見ると、wp_headアクションに_wp_render_title_tagという関数が登録されているのがわかる。

  • add_action( 'wp_head', '_wp_render_title_tag', 1 );
AFFS Simple Code Viewer
Copy

これによりwp_head()を実行すると、wp-includes/general-template.phpの_wp_render_title_tag関数が呼び出される。

  • function _wp_render_title_tag() {
  • if ( ! current_theme_supports( 'title-tag' ) ) {
  • return;
  • }
  • echo '<title>' . wp_get_document_title() . '</title>' . "\n";
  • }
AFFS Simple Code Viewer
Copy

current_theme_supports()は特定の機能が有効になっているか確認している。
ここでは'title-tag'という機能を確認しているが、デフォルトでは無効だからここで終了する。

add_theme_support()で'title-tag'有効することで後続のコードが実行される。
ここでは、wp_get_document_title()を呼び出してタイトルの文字列を取得して、echoでtitleタグと共に出力している。

titleタグの内容を変更する

自動でタイトルを出力してくれるようになったので、次は内容を変更したい。

まず考えられるのが、wp_get_document_title()で用意されているフィルターを使用することだ。

wp_get_document_title()は最初にpre_get_document_titleフィルターを呼び出している。
そして結果がemptyでなければ、そのまま返している。

  • function wp_get_document_title() {
  • $title = apply_filters( 'pre_get_document_title', '' );
  • if ( ! empty( $title ) ) {
  • return $title;
  • }
  • global $page, $paged;
AFFS Simple Code Viewer
Copy

次の記事で紹介した方法でpre_get_document_titleフィルターに登録されている関数を確認すると、なにも無いことがわかる。

WordPress:アクションまたはフィルターに登録されている関数をリストアップする

そのためpre_get_document_titleフィルターを使用すれば、自分で想定したタイトルが生成できる。
しかし、WordPressには個別ページやカテゴリページ、タグページなど様々な種類のページがあり、それぞれ個別の形式でタイトルがフォーマットされることが多い。

一番手っ取り早いのが、wp_get_document_title()の global $page, $paged; 以降をコピーして、必要な部分だけ書き換えることだ。
次のようになる。

  • function my_document_title(){
  • global $page, $paged;
  • $title = array(
  • 'title' => '',
  • );
  • if ( is_404() ) {
  • $title['title'] = __( 'Page not found' );
  • } elseif ( is_search() ) {
  • $title['title'] = sprintf( __( 'Search Results for &#8220;%s&#8221;' ), get_search_query() );
  • } elseif ( is_front_page() ) {
  • $title['title'] = get_bloginfo( 'name', 'display' );
  • } elseif ( is_post_type_archive() ) {
  • $title['title'] = post_type_archive_title( '', false );
  • } elseif ( is_tax() ) {
  • $title['title'] = single_term_title( '', false );
  • } elseif ( is_home() || is_singular() ) {
  • $title['title'] = single_post_title( '', false );
  • } elseif ( is_category() || is_tag() ) {
  • $title['title'] = single_term_title( '', false );
  • } elseif ( is_author() && get_queried_object() ) {
  • $author = get_queried_object();
  • $title['title'] = $author->display_name;
  • } elseif ( is_year() ) {
  • $title['title'] = get_the_date( _x( 'Y', 'yearly archives date format' ) );
  • } elseif ( is_month() ) {
  • $title['title'] = get_the_date( _x( 'F Y', 'monthly archives date format' ) );
  • } elseif ( is_day() ) {
  • $title['title'] = get_the_date();
  • }
  • if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) {
  • /* translators: %s: Page number. */
  • $title['page'] = sprintf( __( 'Page %s' ), max( $paged, $page ) );
  • }
  • if ( is_front_page() ) {
  • $title['tagline'] = get_bloginfo( 'description', 'display' );
  • } else {
  • $title['site'] = get_bloginfo( 'name', 'display' );
  • }
  • $sep = apply_filters( 'document_title_separator', '-' );
  • $title = apply_filters( 'document_title_parts', $title );
  • $title = implode( " $sep ", array_filter( $title ) );
  • $title = apply_filters( 'document_title', $title );
  • return $title;
  • }
  • add_filter('pre_get_document_title', 'my_document_title', 1);
AFFS Simple Code Viewer
Copy

上のコードは書き換えていないので、必要に応じて変更していただきたい。

しかし、ここまでやるならpre_get_document_titleフィルターを利用する必要はない

_wp_render_title_tag()をwp_headアクションから削除して、自作したアクションを登録するのが効率がいい。
この場合、add_theme_support( 'title-tag' )も必要ない。

  • remove_action('wp_head', '_wp_render_title_tag', 1);
  • add_action('wp_head', '_my_render_title_tag', 1);
  • // add_theme_support( 'title-tag' ); ← いらない
  • function _my_render_title_tag(){
  • echo '<title>'.my_document_title().'</title>' . "\n";
  • }
AFFS Simple Code Viewer
Copy

既存のtitleタグは制御できない

これでwp_head()がtitleタグを出力してくれるようになるのだが、テンプレートにtitleタグが記述されているとダブってしまう。
既存のものはプログラムコードで削除できないので、テンプレ―トから手作業で削除する必要がある。

めんどうだが、仕方がない。