カスタム投稿タイプの取得:get_query_varとget_post_typeの違い

※本ブログの目的は個人の備忘録であり、コードは参考用として掲載しています。
実際に使用される際は、ご自身の環境で十分に動作確認を行ってください。
コードの利用によって生じたいかなる問題についても責任を負いかねますので、あらかじめご了承ください。

WordPress でカスタム投稿タイプを扱うとき、よく使うのが

$post_type = get_query_var('post_type') ?: get_post_type();

という書き方です。

一見シンプルで問題なさそうに見えますが、実は 「投稿が存在しない場合に get_post_type() は値を返さない」 という落とし穴があります。
この記事では、このポイントと安全な書き方について解説します。

get_query_var('post_type') とは

get_query_var('post_type') は、現在のクエリ(URLパラメータやWP_Query)に指定されている投稿タイプを返します。

投稿が1件もなくてもクエリとして投稿タイプは指定されているので、値を取得できます。

他にも、色々なクエリに関する情報を取得できます。

// 現在のページ番号を取得
$paged = get_query_var('paged') ?: 1;

// カテゴリーアーカイブで現在のカテゴリースラッグを取得
$cat_slug = get_query_var('category_name');

// タクソノミー「tax」のスラッグを取得
$genre = get_query_var('tax');

get_post_type() とは

一方、get_post_type()現在表示している投稿オブジェクトの投稿タイプを返します。

例えばシングルページでは問題なく動きます。

echo get_post_type(); // "post" や "news" など

ただし、投稿がないと get_post_type() は nullになるという注意点があります。

アーカイブページなどで「投稿が1件も存在しない場合」、get_post_type()何も返しません

get_query_var('post_type') と get_post_type() の違い

例えば下記のようなコードだと

$post_type = get_query_var('post_type') ?: get_post_type();
echo $post_type;

実際の挙動としては、

  • 投稿がある場合 → news など正しく表示される
  • 投稿がない場合 → get_post_type() は空になるが、get_query_var('post_type') が効いて news が表示される

という違いが出ます。

実際の例

例えば、カスタム投稿タイプ news のアーカイブを作ったとします。

<?php
$post_type = get_query_var('post_type') ?: get_post_type();
$post_type_object = get_post_type_object($post_type);

if ( $post_type_object ) {
    $label = $post_type_object->label; // 投稿タイプのラベル
    echo '<h1>' . esc_html($label) . '一覧</h1>';
}

もし get_post_type() のみを使っていたら、投稿が0件のときにタイトルが表示できないという不具合になってしまいます。

まとめ

  • get_query_var('post_type') → クエリに指定された投稿タイプを返す(投稿がなくてもOK)
  • get_post_type() → 表示している投稿オブジェクトの投稿タイプを返す(投稿がなければ空)
  • アーカイブページなどで投稿がない場合を考慮するなら get_query_var('post_type') を優先して使う のが安心

ポイント

投稿がないときでも post_type をちゃんと取得したいなら、get_query_var() を使いましょう。

$post_type = get_query_var('post_type') ?: get_post_type();

参考