検索ワードに該当する記事一覧を表示するsearch.phpを作る [WordPressテーマ作成の手順15]

WordPressのテーマ作成7では、ヘッダー部分に検索フォーム(サーチボックス)を作ったが、その検索結果を一覧表示するテンプレートはまだない。
今回はその、検索ワードにマッチする記事を一覧表示するテンプレート「search.php」を作ります。

手順は、WordPressのテーマ作成13で作った「category.php」をコピーして「search.php」と言う名前にし、タイトル部分を編集。
さらに、ループ部分で、検索ワードにマッチした記事があるかチェックさせる。
function.phpにも検索用の記述を追加する。

本日のINDEX

スポンサーリンク

category.phpをコピーしてsearch.phpを作る

WordPressのテーマ作成13で作った「category.php」をコピーして「search.php」という名前に変更。
このsearch.phpという名のファイルがあれば、WordPressは「検索結果一覧」表示用テンプレートとして使用する。

検索結果一覧の表示用のテンプレートについて

WordPressは、「検索結果一覧」はsearch.phpで表示する。これが無ければindex.phpが使われる。
「検索結果一覧」で、抜粋文を使ったコンパクトな一覧表示をしたいなら、テンプレート名「search.php」のファイルを作る必要がある。

テンプレートの種類と優先順位についてはこちら:
WordPress「テンプレート」の優先順位 | 超初心者のサーバー移転とドメイン移管&ついでにWordPressも!

search.phpの編集

the_search_query()で「検索ワード」をタイトルに出力

search.phpを作ったら、まずはタイトル部分を編集。
タイトルに「検索ワード」を出力させます。
(下図は、「検索フォーム search」の検索ワードで検索した場合のタイトル部分)

本ブログではソースはこのように。

<div class="col-full">
  <div class="wrap-col">
    <section class="searchTtl clearfix">
    <h1><?php the_search_query(); ?> の検索結果</h1>
    </section>
  </div>
</div>

*上記ソースの div.col-full, div.wrap-col は、本ブログのグリッドシステムによるものです。

4行目のthe_search_query()」で「検索ワード」を出力

ループ内で検索ワードにマッチする記事をチェックさせる

次に、記事の一覧部分を編集。
ここはコピー元のcategory.phpとプレビューはまったく同じにするので、ほぼそのまま使えるが、1点だけ変更が必要。
ループ内で「検索ワードにマッチする該当記事があるかどうか」をチェックさせる。

ループの基本形についてはコチラ:投稿用テンプレートsingle.phpを作る(WordPressループの使い方)[WordPressテーマ作成の手順9] | *Web Design 覚え書き*

本ブログではこのように。

<?php
if (have_posts() && get_search_query()) : 
  while (have_posts()) :
    the_post();
    get_template_part('each_exrpt_post');
  endwhile;?>
<!--------------PageNavi--------------->
<div class="col-full">
  <div class="wrap-col">
    <?php
	if (function_exists('page_navi')) :
    page_navi('elm_class=page-nav&edge_type=span');
    endif;?>
  </div>
</div>
<!--------------PageNavi END--------------->
<?php else : ?>
<div class="col-full">
  <div class="wrap-col">
  <p>検索キーワードに該当する記事がございませんでした。<br>
  カテゴリーやタグから探してみてください。</p>
  </div>
</div>
<?php endif; ?>

*上記ソースの div.col-full, div.wrap-col は、本ブログのグリッドシステムによるものです。

ループの最初のif文で、元は「have_posts()」だけだったところにget_search_query()」を条件として追加する。(2行目)これだけでWordPressは検索ワードとマッチする記事があるかどうかを探してくれる。

このあとは変更しなくてOK。ページャー(7〜16行)もそのまま流用。
ただし、検索ワードにマッチした記事がない場合、のっぺらぼうになってしまうので、else文を足して(17行目から)、該当記事が無かった場合のテキストを足してみた。(20,21行目)

function.phpに追記する

上記までで、検索結果をsearch.phpで表示するようになった。
が、このままだとちょっとだけ不都合があるので、function.phpを使って調整する。

0か未入力で検索した場合でもsearch.phpを使うために

検索ワードが未入力のまま検索ボタンを押したり、「0」と入力して検索した場合、search.phpがテンプレートとして使われない(index.phpが使われる)のだそうだ。
そんな時でもsearch.phpで表示させるために、function.phpに以下を追記

function search_template_redirect() {
  global $wp_query;
  $wp_query->is_search = true;
  $wp_query->is_home = false;
  if (file_exists(TEMPLATEPATH . '/search.php')) { 
    include(TEMPLATEPATH . '/search.php');
  }
  exit;
}
if (isset($_GET['s']) && $_GET['s'] == false) {
  add_action('template_redirect', 'search_template_redirect');
}

関数「search_template_redirect」を作って、$wp_queryでsearch.phpを使うように指定。
10行目からのif文で、「s(検索ワード)」が「false(0か未入力)」のとき、関数「search_template_redirect」を実行すると指定。
(WordPressは検索ワードを「s」に格納し$_GETで使用するんだそうです)
template_redirect(11行目)」は「アクションフック」の1つで、WordPressがテンプレートを選ぶ直前に実行されるんだって。

検索一覧に表示させたくない記事を除外する

検索ワードにマッチしても、検索一覧に表示させたくない記事(投稿・固定ページ)もある。
本ブログの場合は、固定ページの「about」や「全記事一覧」をはずしたかった。表示されても意味無いので…。
そんな時は、以下のソースで記事のIDを指定すれば除外してくれる。

function fb_search_filter($query) {
  if ( !$query -> is_admin && $query -> is_search) {
    $query -> set('post__not_in', array(20, 155) );
  }
  return $query;
}
add_filter( 'pre_get_posts', 'fb_search_filter' );

3行目の「’post__not_in’, array(20, 155) 」の配列の数字がID。
カンマ(,)で区切って複数指定できる。
pre_get_posts(7行目)」もWordPressの「アクションフック」の1つで、管理画面を含むすべての記事の取得のタイミングで実行されるんだって。
関数「fb_search_filter」でID20と155の記事を除外する指定をして、pre_get_posts を使って記事の抽出条件を変更(「fb_search_filter」を呼び出し)しているのね。

記事のIDとは
管理画面の各記事(投稿も固定ページも)の編集画面のアドレスバーで、「post=」で確認できる。
例えば、「http://○○○.com/wp-admin/post.php?post=20&action=edit」だったら、IDは20。

関連記事

WordPressの Embedカードのリンクを別ウィンドウで開く(PCのみ。スマホ・タブレットはそのまま)

WordPressの Embedカード(ブログカード)のリンクは、デフォルトでは同ウィンドウで開くようになっていますが、これを別ウィンドウ(別タブ)で開くように [記事を読む]

WordPressの Embedカードのスタイルを編集する方法2つ

前回の記事で、WordPress 4.5 の Embedカード(ブログカード)の「テンプレートの構成」や「HTML要素のクラス名」などを調べました。これを元に、 [記事を読む]

WordPress4.5で Embedカードの PHPファイルの構造がだいぶ変わったみたい

前回から WordPressの Embedカード(ブログカード)について調べたことをメモっています。 今回は Embedカードの PHPファイルの構造について [記事を読む]

Leave a Comment

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。

^