制作Note

wordpressの検索機能で条件分岐をする際、is_pageやis_singleだと曖昧になる

wordpressの検索機能を使って検索するときに、固定ページと投稿が合わさって表示されるのですが、各々の表示をif文を使って条件分岐して表示したいと思ったときの記述でis_pageやis_singleでは上手く制御できませんでした。

下記のように記述すると上手くいきました。

<?php if ( (is_search() && get_post_type() === 'post') && has_post_thumbnail() ) : ?>
    //投稿ページでかつサムネイル画像がある投稿

    <?php elseif ( (is_search() && get_post_type() === 'page')) : ?>
    //固定ページのみ対象

<?php endif; ?>
更に深掘り

なぜ is_page() や is_single() ではうまくいかなかったのか?

is_page() と is_single() の動作原理

これらの関数は、特定のページまたは投稿を表示している場合に true を返します。つまり、検索結果一覧ページ自体では is_page() も is_single() も false になります。これらの関数は、特定の固定ページや投稿の詳細ページを表示しているときに使うことを想定されています。

get_post_type() を使用する理由と仕組み

get_post_type() の役割

get_post_type() は、現在の投稿(ループ内で処理されている投稿)の投稿タイプを返します。例えば、投稿なら ‘post’、固定ページなら ‘page’、カスタム投稿タイプならそのカスタム投稿タイプの名前が返されます。

検索結果一覧ページでの利用

検索結果一覧ページでは、WordPress は検索結果をループで順番に処理していきます。ループ内で get_post_type() を使うことで、現在処理されている投稿が投稿なのか固定ページなのかを判別できます。

コードの解説と改善点

  • 冗長な is_search() の排除:
    get_post_type() はループ内で使用されることを前提としているため、検索結果一覧ページ以外では意味を持ちません。
  • elseif の使用:
    elseif は、前の条件が false だった場合にのみ評価されるため、条件の重複を防ぎ、効率的な処理を実現します。
  • 条件の明確化:
    コメントだけでなく、変数を使用するなどして条件を明確にすることで、コードの可読性を向上させることができます。

コード例(改善案)

<?php
  //投稿ページでかつサムネイル画像がある投稿
  if ( get_post_type() === 'post' && has_post_thumbnail() ) : ?>
      // 投稿ページの処理
      // 例: 投稿のタイトル、サムネイル画像を表示
      echo '<div class="search-result-post">';
      the_title( '<h2 class="entry-title"><a href="' . get_permalink() . '" rel="bookmark">', '</a></h2>' );
      the_post_thumbnail( 'thumbnail' ); // サムネイル画像を表示
      the_excerpt(); // 抜粋を表示
      echo '</div>';

  //固定ページのみ対象
  elseif ( get_post_type() === 'page' ) : ?>
      // 固定ページの処理
      // 例: 固定ページのタイトルと内容を表示
      echo '<div class="search-result-page">';
      the_title( '<h2 class="entry-title"><a href="' . get_permalink() . '" rel="bookmark">', '</a></h2>' );
      the_content();
      echo '</div>';

  //その他の投稿タイプ
  else : ?>
      // その他の投稿タイプの処理 (カスタム投稿タイプなど)
      echo '<div class="search-result-other">';
      the_title( '<h2 class="entry-title"><a href="' . get_permalink() . '" rel="bookmark">', '</a></h2>' );
      the_excerpt();
      echo '</div>';

  endif;
?>

より複雑な条件分岐の例
例えば、特定のカテゴリーの投稿のみ異なる表示にしたい場合は、in_category() 関数を使用できます。

<?php
if ( get_post_type() === 'post' && in_category( 'news' ) ) : ?>
    // news カテゴリーの投稿の処理
    // ...
<?php elseif ( get_post_type() === 'page' ) : ?>
    // 固定ページの処理
    // ...
<?php endif; ?>

補足

検索結果テンプレートファイル: WordPress のテーマによっては、検索結果一覧ページのテンプレートファイル (search.php) が存在しない場合があります。その場合は、index.php が使用されることがあります。

pre_get_posts アクション: より高度な検索結果の制御を行う場合は、pre_get_posts アクションを利用することも検討してください。

まとめ

今回のコードでは、get_post_type() を使用することで、検索結果一覧ページで投稿タイプを判別し、それぞれのタイプに対して異なる表示処理を行うことができました。 is_page() や is_single() は特定のページや投稿を表示している場合に使う関数であり、検索結果一覧ページでは適切に動作しないことが理解できました。

改善案として、冗長な is_search() の記述を排除し、条件分岐を明確にすることで、より可読性の高いコードにすることができます。