WordPress4.1~4.3.xでカスタムフィールドを使い、投稿ごとにタイトルタグを自由に編集する方法(フィルターフック使用)

2015年10月12日

4年前の2011年5月に『初心者でもプラグインを使わずにtitle,meta keyword,descriptionを投稿ごとに変える[WordPress使えそうなスニペットシリーズ]』という記事を書き、昨2014年10月にコードを見なおして記事を改訂しました。

しかし、2015年1月にリリースされたWordPress4.1からは、タイトルタグはheader.phpではなくfunctions.phpで定義して出力する方法が推奨と変わりました。
そこで、カスタムフィールドを使って投稿ごとにtitle要素を任意の文字列に変更するためのコードを書きなおしてみました。

仕様

  • 既にfunctions.phpにadd_theme_support( 'title-tag' );が入っている前提
  • カスタマイズ対象は個別の記事(投稿、固定ページ、カスタム投稿タイプの記事)
  • 「my_title」というキーのカスタムフィールドに値が入っていれば、その文字列をそのまま利用
  • 何も設定しない場合はWordPressのwp_title関数の標準仕様にまかせる

以下のコードを使用中のテーマのfunctions.phpに追記します。

上記コードだとサイト名の出力部分も含めてカスタマイズしますが、「○○○ | サイト名」の形式はそのままで、○○○の部分だけ変えたい場合は以下の「その2」を使ってください。

【2015.10.15追記】区切り文字(|)とサイト名の間にスペースがほしいというお声をいただいたので一部修正しました。

注意事項

この程度の短いコードでも個人的なハマリポイントが2つほどあったので注記しておきます。

最初に書いたコードはコレでした。

//失敗コード例
function mypace_custom_title( $title ){
  if( is_singular() ){
    $title = get_post_meta( $post->ID, 'my_title', true ); //ここが問題
    if( $title ){
      return esc_html( $title );
    }
  }
return $title;
}
add_filter( 'wp_title', 'mypace_custom_title', 10, 2 );

失敗ポイント1. 投稿IDを取得できていない

カスタムフィールドの取得コードは

  • get_post_meta( $post->ID, ‘my_title’, true );
  • $post->my_title

などという感じで、$postオブジェクトを使ったものがよく紹介されていますが、今回は投稿ループ内ではなくfunctions.phpでの処理ですので、そのままでは$postから情報が取れません。
そのため投稿IDはget_the_ID関数で取得したものを使うように書き換えました。

get_the_IDを使う代わりに、 global $post; でグローバル宣言をしても同様の結果になりましたが、日本語版Codexに

グローバルの $post オブジェクトの ID プロパティ(例: $post->ID)を使うこともできますが、これは常にあなたが意図したものとは限りません。

とあるため一応避けました。ただ、global $post;の方法でもよほど問題ないとは思います。
※このあたりの違いについては詳しい方補足いただけると嬉しいです。

参考:関数リファレンス/get post meta – WordPress Codex 日本語版

失敗ポイント2. $titleの上書きタイミングが早過ぎる

当初、カスタマイズさせる方の変数名も $title を使っていて、カスタムフィールドの値の有無を判定する前にいきなり $title にカスタムフィールドの値を代入していました。

これだと、カスタムフィールドに値があるときはいいんですが、カスタムフィールドが空の時も$titleを上書きしてしまうため、出力されるタイトルタグも空になってしまいます。
そのため、カスタムフィールドの値は別の変数($my_title)に入れて処理しています。

以上です。

「WordPress タイトルタグ カスタムフィールド」とかでググっても、今までのheader.phpにベタ貼りする方法しか引っかかってこなかったので書きました。
WordPressはバージョンアップにともなって、できるだけアクションフックやフィルターフックでカスタマイズしてもらいたいという雰囲気が強くなってきている気がしますので、逃げずに向き合っていかねばと思いました。