小金井にあるWEB制作会社の備忘録

MEMORANDUM

WordPress(ワードプレス)でサイト内検索機能をカスタマイズ

ワードプレスを使用して運用されているサイトで投稿した記事を検索したい(サイト内検索)というご相談を受けた際に調べた内容をメモ。

サイト内検索の実装手順

検索フォームを準備する

まずは、検索フォームを準備します。ソースを該当ページに直書きするでも良いですが、使いまわせるように別ファイル(searchform.php)で作成。
テーマ内にファイルをアップしたら、読み込み専用のソースで読み込みます。

PHP

<?php get_template_part('searchform'); ?>

searchform.php

今回はカスタム投稿から投稿された記事に対して、タグ、カテゴリー(カスタムタクソノミー)を使用して検索する方法を実装。

<form method="get" id="searchform" action="<?php bloginfo('url'); ?>">
    <input type="hidden" name="s" id="s">
    <input type="hidden" name="post_type" value="<?php echo get_post_type( $post ); ?>">

    <select name='s-tag'>
    <option value="">全てのタグ</option>
    <?php
    if($terms = get_terms('contents-tag')) {
        foreach ( $terms as $term ) {
            echo('<option value="'.esc_html( $term->slug ).'">'.esc_html($term->name).'</option>');
        }
    }
    ?>
    </select>
    
    <select name="s-cat">
    <option value="">全てのカテゴリー</option>
    <?php
    if($terms = get_terms('contents-cat')) {
        foreach ( $terms as $term ) {
            echo('<option value="'.esc_html( $term->slug ).'">'.esc_html($term->name).'</option>');
        }
    }
    ?>
    </select>

    <input type="submit" value="検索">
</form>

ワードプレスの検索機能は「s」のパラメータ(キーワード検索)を基準に行われる、キーワードの指定が不要な場合でも「hidden」要素で「s」の値を返す必要があります。
また、一般的にサイト内検索では全てのページが対象となってしまうので、「name=”post_type”」の部分で該当する投稿タイプを限定しています。

検索結果ページの準備

ワードプレスで検索を行った際に表示されるページは「search.php」が使用されます。
そのままで良い場合は別として、検索結果ごとに表示するページを変更した場合は以下のコードを追加する必要があります。

検索結果ページを投稿タイプ別に切り分ける場合の対応

function.php
function custom_template_include($template){
	if(is_search()){
		$post_types = get_query_var('post_type');
		$new_template = locate_template(array('search-'.$post_types.'.php'));
		if($new_template != ''){
			return $new_template;
		}
	}
	return $template;
}
add_filter('template_include', 'custom_template_include', 99);

上記コードを「function.php」に追記することで、他のページ同様に「search-○○○○(カスタム投稿名).php」が使用可能にできます。

search.php(search-○○○○(カスタム投稿名).php)
<?php
// searchform.phpから送られてきたパラメーターを取得
$post_type = wp_unslash($_GET['post_type']);
$s-tag = wp_unslash($_GET['s-tag']);
$s-cat = wp_unslash($_GET['s-cat']);

// 絞り込み条件を追加
if($s-tag) {
	$taxquery_tag = array(
		'taxonomy' => 'contents-tag',
		'terms' => $s-tag,
		'field' => 'slug',
	);
}

if($s-cat) {
	$taxquery_cate = array(
		'taxonomy' => 'contents-cat',
		'terms' => $s-cat,
		'field' => 'slug',
	);
}

$args = array(
	'post_type' => $post_type,
	'paged' => get_query_var('paged'),
	's' => get_search_query(),
	'tax_query' => array(
		'relation' => 'AND',
		$taxquery_tag,
		$taxquery_cat,
	),
);
$sub_query = new WP_Query($args);
?>

<ul class="newslist__list">

<?php if ( $sub_query->have_posts() ) : ?>

<p><?php echo $sub_query->post_count; ?>件<span> / <?php echo $sub_query->found_posts; ?> 件</span></p>

<?php while ( $sub_query->have_posts() ) : $sub_query->the_post(); ?>

<!-- ここにループ処理 -->
<li>
<a href="<?php the_permalink(); ?>"><?php echo get_the_title(); ?></a>
</li>
<!-- ここまでループ処理 -->

<?php endwhile; ?>
</ul>

<nav class="pagination">
<?php
//ページネーション
	$bignum = 999999999;
	echo paginate_links( array(
		'base' => str_replace( $bignum, '%#%', esc_url( get_pagenum_link($bignum) ) ),
		'format' => '',
		'current' => max( 1, get_query_var('paged') ),
		'total' => $sub_query->max_num_pages,
		'prev_text' => '&larr;',
		'next_text' => '&rarr;',
		'type' => 'list',
		'end_size' => 3,
		'mid_size' => 3
  ) );
?>
</nav>

<?php else: ?>

<p>検索されたキーワードにマッチする記事はありませんでした</p>

<?php endif; ?>

<?php wp_reset_postdata(); ?>

WP_Query」を使用して、条件に合った投稿リストを取得できるように値を設定。
リスト取得後は「wp_reset_postdata」使用して、変更していた取得条件をリセットしています。