WordPress

WordPressの検索表示をカスタマイズする

Category

WordPress

ちょっと久しぶりにWordPressネタを書こうと思います。
WordPressでは簡単に検索フォームを設置することができますが、デフォルトの設定では「検索フォームの見栄えがよくない」「検索時に該当件数を表示したい」「カスタムフィールドで作成した項目は検索にヒットしない」等、WordPressをカスタマイズしてオリジナルのサイトを構築する場合、「こういった感じにできないかなー?」っといった場合がよくあります。
検索結果の表示を指定したものに変更できる"Search Everything"といったプラグインもありますが、私の場合、検索やカスタム投稿タイプ等の主要な機能に関しては、出来る限りプラグインを使用したくないわけです...(WordPress本体のアップデート時やプラグインのアップデート時に機能しなくなったり、表示がおかしくなったりする場合があるからなのですが、WordPressのプラグインは便利で優れたものが多いのも確かです。今回の記事は、テンプレートファイルをいじりたい方向けの記事かもしれません)。
そこで今回は、プラグインを使わずにWordPressの検索結果をカスタマイズする方法を書こうと思います。

Keyword:検索結果,search.php,query.php

WordPressの検索表示をカスタマイズ

以下の手順で紹介していきます。
テキストリンクをクリックすると、その箇所までページがスクロールします。

  1. 検索フォームを変更する
  2. 検索結果に「入力した検索ワード」と「該当件数」を表示する
  3. 検索結果から除外したいカテゴリーやページを指定する
  4. カスタムフィールドの項目も検索対象に含める
  5. 検索結果のページタイトルを変更する

検索フォームを変更する

WordPressに検索フォームを設置するのはそれほど難しくはありません。
“ドメイン/?s=検索ワード”のようにパラメータsに対して検索ワードを入れるだけで機能してくれますので、検索フォームを表示させたいテンプレートファイルに以下を記述します(header.phpに記述するものとして説明します)。

header.php

<form action="<?php bloginfo('url'); ?>/" method="get">
<input type="text" name="s">
<input type="submit" value="検索">
</form>

説明

<?php bloginfo(‘url’); ?>は、TOPページのURLを示すテンプレートタグですが、直接TOPページのURLを記述しても構いません(1行目)。

このままですと、検索ボックスと検索ボタンの見栄えがよいとは言えませんので、検索ボックスはCSSで見た目を調整し、検索ボタンはロールオーバーする画像ボタンに変更します。まずは検索ボックスの見た目をCSSで調整します。

CSS

/* 検索ボックスのスタイル */
.search_box {
    width: 250px;
    height: 25px;
    border: 1px solid #ABADB3;
}

説明

検索ボックスの幅・高さ、ボーダーの太さ・種類・カラーを指定します(レイアウト等の調整はデザインに合わせて行ってください)。

上記CSSを適応し、検索ボタンをロールオーバーする画像に変更します。
先程記述したheader.phpを変更します。

header.php

<form action="<?php bloginfo('url'); ?>/" method="get">
<input type="text" name="s" class="search_box">
<input type="image" src="<?php bloginfo('template_directory'); ?>/image/search.png" onmouseover="this.src='<?php bloginfo('template_directory'); ?>/image/search_hover.png'" onmouseout="this.src='<?php bloginfo('template_directory'); ?>/image/search.png'" width="55" height="25" alt="検索">
</form>

説明

検索ボックスにCSSのクラスを適応します(2行目)。
検索ボタンを画像にしますので、typeを”submit”から”image”に変更します(3行目)。
<?php bloginfo(‘template_directory’); ?>は、テンプレートファイルが格納されているディレクトリを示すテンプレートタグです(3行目)。
“onmouseover~”でマウスオバー時の画像を指定し、”onmouseout~”でマウスアウト時の画像を指定します(3行目)。
画像ボタンのサイズは、デザインに合わせて調整してください。

▼検索フォームのイメージ

検索フォーム

検索結果に「入力した検索ワード」と「該当件数」を表示する

検索結果を表示する際、入力した検索ワードに対して、何件の該当記事があるかを表示させる方法を紹介します(「“○○○○○”で検索した結果、○件の記事が見つかりました」と表示させる検索ページでよく見かけるアレです)。
例えば、検索結果が複数ページに分かれて表示される場合(検索結果が多い場合)、何件の記事が入力した検索ワードに該当するか分かった方がユーザビリティも良くなります(検索結果が多かった場合、再検索することで目的のページも探しやすくなりますよね!)。

search.phpを作成し、検索結果表示部分に以下を記述します。

search.php

<?php $allsearch =& new WP_Query("s=$s&posts_per_page=-1");
$key = wp_specialchars($s, 1);
$count = $allsearch->post_count;
if($count!=0){
// 検索結果を表示:該当記事あり
    echo '<p>“<strong>'.$key.'</strong>”で検索した結果、<strong>'.$count.'</strong>件の記事が見つかりました</p>';
} 
else {
// 検索結果を表示:該当記事なし
    echo '<p>“<strong>'.$key.'</strong>”で検索した結果、関連する記事は見つかりませんでした</p>';
}
?>

説明

search.phpがない場合、index.phpが使用されますので、検索結果表示用にsearch.phpを作成してやります。上記は、ループ処理の前に記述してください。
検索結果に該当する記事がある場合「“○○○○○”で検索した結果、○件の記事が見つかりました」と表示され、検索結果に該当する記事がない場合「“○○○○○”で検索した結果、関連する記事は見つかりませんでした」と表示されます(該当する記事がある場合とない場合で条件分岐させます)。
echo文の箇所は、サイトのデザインに合わせていろいろ変更してみてください。

[検索に該当する記事の表示部分に関して]
上記は、検索ワードに対して「入力したワード」と「該当件数」を表示させる方法です。
検索に該当する記事の表示部分は、ループ内に記述してください。 当記事ではこちらの説明は割愛しますので、テンプレートタグを組み合わせてお好きなようにカスタマイズしてみてください(個人的には、TOPページもしくはカテゴリーページ等で使用しているループ部分のソースを使い回せば楽だと思います)。

表示のさせ方はいろいろありますが、「入力したワード」と「該当件数」の表示部分を吹き出し風にしてみるのも面白いかと思います。また、該当記事がない場合、検索結果の直ぐ下に”検索フォーム”を表示して再検索を促せば、ユーザビリティもよくなります。検索に該当する記事の表示部分に関しても、タイトル・日程・サムネイル・概要等を表示してやることで、目的のページを探しやすくなります。
サイトに合わせて、search.phpをいろいろと変更してみてください!

以下の画像は「こんな表示もできますよ」っというイメージになります(当サイトのキャプチャーを撮っただけの手抜きですが…)。

▼検索結果ページのイメージ

検索結果

※画像をクリックすると拡大表示されます

検索結果から除外したいカテゴリーやページを指定する

WordPressのデフォルト設定では、投稿ページ・カスタム投稿ページ・固定ページの記事が検索対象となります。「通常の投稿ページ以外は検索対象から除外したい(固定ページとカスタム投稿ページの記事は検索対象に含めたくない)」「固定ページだけ検索対象から除外したい」「一部のカテゴリーの記事は除外したい」「特定の記事のみ除外したい」等、検索対象を設定したい場合あります。
このような場合、functions.phpに以下の記述をします。

1.検索結果から固定ページとカスタム投稿ページを除外する

functions.php

// 検索結果から通常投稿以外のページを除外
function search_filter($query) {
  if (!$query -> is_admin && $query -> is_search) {
    $query -> set('post_type', 'post');
  }
  return $query;
}
add_filter('pre_get_posts', 'search_filter');

補足

3行目は単純に”if ($query -> is_search) {“でも構わないのですが、こうすると管理画面からの検索でも除外されてしまいますので、個人的には”is_admin”でリクエストしたページが管理者ページかどうかを調べて上で、”!”を付けて除外する方がよいと思います。”is_admin”は、”ダッシュボードまたは管理パネルが表示されている場合”といった場合に使用する条件分岐タグです。
注意点としては、4行目で”post(通常の投稿)”のみを指定していますので、カスタム投稿タイプの記事も検索対象にはならない点です。固定ページのみを除外したい場合は、次に紹介する”2.検索結果から固定ページを除外する”を記述しましょう。

2.検索結果から固定ページを除外する

functions.php

// 検索結果から固定ページを除外
function search_filter($query) {
  if (!$query -> is_admin && $query -> is_search) {
    $query -> set('post_type', array('post', 'ポストタイプ名'));
  }
  return $query;
}
add_filter('pre_get_posts', 'search_filter');

補足

4行目の配列”array”を使って、通常投稿の”post”とカスタム投稿の”ポストタイプ名”を指定します。これで、投稿ページとカスタム投稿ページは検索対象にして、固定ページのみ検索対象から除外されます。

3.検索結果から除外したいカテゴリーを指定する

functions.php

// 検索結果から除外したいカテゴリーを指定
function search_filter($query) {
  if (!$query -> is_admin && $query -> is_search) {
    $query -> set('category__not_in', array(1,2));
  }
  return $query;
}
add_filter('pre_get_posts', 'search_filter');

補足

4行目の”category__not_in”は、”指定した複数のカテゴリーのいずれにもに含まれない投稿のみを表示”といった場合に使用する引数で、”category__not_in (配列:カテゴリーIDの配列)”といったように使います。配列”array(1,2)”には、除外したいカテゴリーIDを指定します。

4.検索結果から除外したいページを指定する

functions.php

// 検索結果から除外したいページを指定
function search_filter($query) {
  if (!$query -> is_admin && $query -> is_search) {
    $query -> set('post__not_in', array(3,5,7));
  }
  return $query;
}
add_filter('pre_get_posts', 'search_filter');

補足

4行目の”post__not_in”は、”指定した複数の記事のいずれにもに含まれない投稿のみを表示”といった場合に使用する引数で、”post__not_in (配列:記事のIDの配列)”といったように使います。配列”array(3,5,7)”には、除外したい記事のIDを指定します。

カスタムフィールドの項目も検索対象に含める

WordPressのデフォルト設定では、カスタムフィールドで作成した項目は検索対象に含まれません。検索対象に含める方法はいくつかあると思うのですが、query.phpに一部追記して、カスタムフィールドで作成した項目も検索対象に含まれるようにします。
query.phpは、wp-includesディレクトリ内にあります。
まず、2190行目あたりにある”$searchand = ‘ AND ‘;”といった記述を探します。そして、その直ぐ下に以下を記述します(2012.3.11時点の最新バージョン3.3.1で説明)。

query.php

// カスタムフィールドを検索対象に含める
$csql = "SELECT post_id FROM $wpdb->postmeta";
$csql .= " WHERE meta_key NOT LIKE '\\_%' AND meta_value LIKE '{$n}{$term}{$n}'";
$post_ids = $wpdb->get_col($csql);
if (count($post_ids)) {
      $search .= " OR ($wpdb->posts.ID IN (".implode(',', $post_ids)."))";
}

説明

query.phpは、WordPressのコアファイルですので、WordPress本体のバージョンアップの際は上書きしてしまわないようにご注意ください(アップデート後、忘れずに追記するようにしましょう)。
WordPressには、データベース操作用のクラス関数である”wpdb”が用意されています。wpdbクラスに関しての詳細は、WordPressのCodexをご参照ください。
⇒ WordPress Codex ~関数リファレンス/wpdb Class~

検索結果のページタイトルを変更する

最後に、検索結果が表示された際の”ページタイトル”も調整しましょう。
検索結果表示時の内容とページタイトルを同じにします。また、投稿ページ・カスタム投稿ページ・カテゴリーページ・固定ページのタイトルのことも考えて条件分岐させます。
header.phpに以下を記述します。

header.php

// ページタイトルの振り分け
<?php
if (is_search()) {
    $allsearch =& new WP_Query("s=$s&posts_per_page=-1");
    $key = wp_specialchars($s, 1);
    $count = $allsearch->post_count;
    $count!=0;
        echo '“'.$key.'”での検索結果('.$count.'件) | ';
        bloginfo('name');
    }
else {
wp_title('|', true, 'right');
bloginfo('name');
}
?>

説明

ヘッダーの<title>~</title>の間に記述してください。
3~10行目が検索結果ページで表示されるページタイトルの条件文、11~14行目がその他のページで表示されるページタイトルの条件文となります(表示内容は以下参照)。
●検索結果ページのタイトル
「“○○○○○”での検索結果(○件) | サイト名」
●その他のページのタイトル
「ページタイトル | サイト名」

ページタイトルの表示方法に関しては、当サイトの記事「WordPressでよく使うテンプレートタグの覚え書き」の最初の方で紹介していますので、よかったらご覧ください。

▼ページタイトルの表示イメージ

ページタイトル

List

関連記事(※当記事と関連性が高いと思われる記事)

WordPressのアイキャッチ画像

2012/04/12
WordPressのアイキャッチ画像
スコア:21 ※スコアの数値が大きいほど、関連性の高い記事です。 以下の内容で紹介していきます。※テキストリンクをクリックするとその箇所までページがスクロールします。 アイキャッチ画像の基本的な使い方 アイキャッチ画像の切り替え(指定... 続きを読む...

おすすめ書籍・商品(※当記事と関連性が高いと思われる書籍・商品)

ページの先頭へ