絞り込み検索導入~検索結果表示

事前準備が済み検索フォームが完成したら次は検索結果の表示です。念のため検索フォームも改めて載せておきます。

すべての山
百名山

もくじ

  1. 事前準備編 ※別ページ
  2. 絞り込み検索フォーム作成 ※別ページ
    ※まずこれらのページを読んでおくと検索結果表示への理解が深まります。
  3. 検索結果表示
    1. PHP全コード
    2. 検索条件の表示
    3. 備忘録

PHP全コード

検索結果の表示にはsearch.phpというファイルが使用されており、まずはこれを親テーマから子テーマの直下にコピペします。そして中身をいじっていくわけですが、まずは完成形を貼っておきます。検索フォームのベース作りから検索結果の表示まで、以下のサイトが大いに役立ちました。何度読み返したかわかりません。

絞り込み検索をプラグインを使わずに実装

<?php
/**
 * The template for displaying search results pages.
 *
 * @package First
 */

get_header(); ?>

	<section id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

			<header class="page-header">
				<h3><?php
				 $s = $_GET['s'];
				 $area = $_GET['area'];
				 $tag = $_GET['post_tag'];

				 if($tag){
				 $taxquerysp[] = array(
				 	 'taxonomy'=>'post_tag',
				 	 'terms'=> $tag,
				 	 'include_children'=>false,
				 	 'field'=>'slug',
				 	 'operator'=>'AND'
				 	 );
				 }

				 if($area){
         $taxquerysp[] = array(
            'taxonomy'=>'area',
            'terms'=> $area,
            'include_children'=>false,
            'field'=>'slug',
            'operator'=>'AND'
            );
					}
				 $taxquerysp['relation'] = 'AND';
					?>

				<?php if($s){ ?>検索キーワード:<?php echo $s; }?><br>
				<?php
			 	if($tag){ if (in_array('百名山', $tag)) { ?>百名山から絞り込み<br>
					<?php
			 	}else if (in_array('登山', $tag)) { ?>全ての山の記事から絞り込み<br>
					<?php
			 	}else{ }} ?>
				 	<?php if (is_array($area)) { ?>都道府県:<?php
					 	foreach($area as $val){
							if ($val === end($area)) {
									echo get_term_by('slug',$val,"area")->name; ?><br><?php
    					}else{
									echo get_term_by('slug',$val,"area")->name."<br>山:";
									}
								}
							}	?>
					<?php if (count($tag) > 1) { ?>検索条件:<?php
						$result = array_slice($tag, 1);
						foreach($result as $key => $value) {
							if ($value === end($tag)) {
								 echo $value;
							}else{
								 echo $value."、";
								 }
							 }
						 } ?>
			 </h3>

			</header><!-- .page-header -->

			<?php
			query_posts( array(
					's' => $s,
					'tax_query' => $taxquerysp,
					'paged' => $paged,
			    )
			);
			?>

			<?php /* Start the Loop */ ?>
			<?php if ( have_posts() ) :  while ( have_posts() ) : the_post(); ?>

				<?php get_template_part( 'content', get_post_format() ); ?>

			<?php endwhile; ?>

			<?php
			the_posts_pagination( array(
				'prev_text' => __( '« Previous', 'first' ),
				'next_text' => __( 'Next »', 'first' ),
			) );
			?>

		<?php else : ?>

			<?php get_template_part( 'content', 'none' ); ?>

		<?php endif;
		wp_reset_query(); ?>

		</main><!-- #main -->
	</section><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

絞り込み検索で重要なのはquery_postsで検索結果の一覧を表示していることで、今回のケースだとカスタムタクソノミー(area)やタグ(post_tag)について

'operator'=>'AND'

というパラメータでAND検索にするかOR検索にするかをコントロールしています。今回は絞り込み検索なので全ての条件が合致した場合を表示するためAND検索にしています。

検索結果のページに必須ではありませんが、何を条件に検索したのかが分かりやすいよう検索条件を表示するようにしました。ラジオボタンとチェックボックスに同じタグから情報を引っ張ってきていたので検索条件を自動で表示させるのに少し苦労しましたが何とかなりました。以下にそれぞれの表示方法を備忘録も兼ねて記していきます。

検索条件の表示

まずはフリーワードの表示。これは簡単です。

<?php if($s){ ?>検索キーワード:<?php echo $s; ?>

次に全ての山の記事から絞り込んでいるか百名山で限定しているか、という表示。ここからややこしくなっていきます。

<?php
if($tag){ if (in_array('百名山', $tag)) { ?>百名山から絞り込み<br>
	<?php
}else if (in_array('登山', $tag)) { ?>全ての山の記事から絞り込み<br>
	<?php
}else{ }} ?>

上記コードの最後にelseでタグが百名山でも登山でもない場合を指定しているのは、このsearch.phpは通常の検索でも使われるファイルなので記事全体から検索される場合の表示も記しておく必要があるからです。

次に都道府県と山の名前についてです。

<?php if (is_array($area)) { ?>都道府県:<?php
		foreach($area as $val){
			if ($val === end($area)) {
				echo get_term_by('slug',$val,"area")->name; ?><br><?php
    			}else{
				echo get_term_by('slug',$val,"area")->name."<br>山:";
				}
			  }
			}	?>

都道府県、山の名前共にareaというカスタムタクソノミーに含まれているので少し厄介です。name属性の値をarea[]とすることで配列として扱われるようにし、二つ目(都道府県に続いて山の名前)がある場合は山の名前が表示されるように設定しました。

最後に温泉と御朱印の検索条件の表示についてです。実はこれが結構厄介でした。上記「百名山」「登山」も「温泉」「御朱印」と同じようにpost_tagというname属性で動かしているので単純に検索に使用されたタグを全表示すると百名山もしくは登山という単語が必ず検索条件として表示されてしまいます。これを避けるため、以下のようなコードとしました:

<?php if (count($tag) > 1) { ?>検索条件:<?php
		$result = array_slice($tag, 1);
		foreach($result as $key => $value) {
			if ($value === end($tag)) {
				 echo $value;
			}else{
				 echo $value."、";
				 }
			  }
			} ?>

count($tag)にてタグの数が2つ以上あるかどうかを確認し、2つ以上ある場合のみ検索条件として表示するようにしています(「百名山」と「登山」もタグなのでタグは検索にひとつは必ず含まれている)。array_sliceとは配列の任意の場所から表示を開始するという関数で、$tag, 1と書けば2つ目から表示されることになります。あとは温泉と御朱印の両方ある場合は「、」で繋げ、いずれかひとつの場合は「、」を表示させないように設定しました。「温泉」と「御朱印」をタグではなく別のカスタムタクソノミーで登録していればこんなややこしいことは不要になりますが勉強にはなりました。

参考URL:PHP 配列の一部を取り出して取得する array_slice()

備忘録

query_postで特に重要なのは変数paged。これは現在何ページ目にいるかという値を指定するもので、この値が指定されていないとページ送りの2ページ以降で常に1ページ目の内容が表示されます。ページ送りはかなり苦戦しましたがこちらのサイトで方法を見つけられました。
【WordPress】ページ送りで2ページ目以降が表示されない時
また、query_postで表示する場合、wp_reset_queryがセットで入ってくることを忘れない。

<?php
query_posts( array(
   's' => $s,
   'tax_query' => $taxquerysp,
   'paged' => $paged,
    )
);
?>

<?php endif;
wp_reset_query(); ?>

これで絞り込み検索の検索結果が条件も含め表示されるようになりました。絞り込み検索は不動産サイトや旅行サイト、ECサイトなど様々な場所で使われているので今後もブラッシュアップさせて知識を深めていきたい。