こんにちは。やまぐちなな(@nana_winter_web )です
今回は、制作実績の絞り込み検索を例に、アーカイブページ内のフォームから絞り込み検索をするという仕様の検索フォームを作ります。
今回は、カテゴリー(ターム)を利用して絞り込んでいますが、WP_Queryの条件に追加できるものであれば、なんでも絞り込みできます。 プラグインを利用する場合に比べて複雑な条件や凝ったデザインでも対応しやすいのが良いですね。
今回の仕様
worksというカスタム投稿タイプの記事を「works_item」というタクソノミーのターム(Webサイト、DTPなど)で絞り込みます。
WordPressのバージョンは5.2.9、PHPのバージョンは7.3.2で動作確認をしています。
クエリ変数に値を追加
$_GETから値を取得しても良いですが、WordPress推奨の方法ではないので、クエリ変数を利用します。functions.phpに下記のコードを追加。
/**
* クエリバーに値を追加.
*
* @param Array $vars 既存のクエリ変数.
* @return Array $vars クエリ変数.
*/
function theme_query_vars( $vars ) {
$vars[] = 'works_item'; // 必要に応じて追加.
return $vars;
}
add_filter( 'query_vars', 'theme_query_vars' );
$varsに今後作る検索フォーム内のinput
・select
・textarea
などのname属性の値を代入します。
$vars[] = 'works_item';
の部分は検索条件の数だけ増やします。
フォーム部分を作る
複数箇所で検索フォームを利用することになるので、別ファイルにして管理しやすくします。
テーマフォルダー内に「searchform.php」というファイルを作ります。 わかりやすければ、ファイル名は適当で良いです。
action属性はhome_url()
を指定。
formタグ内に<input type="hidden" name="s" value="">
のタグを必ず入れてください。
value属性は空にしておきます。
検索結果のテンプレートを表示させるために「s」のURLパラメーターが必要なので入れています。
type属性をtextなどにすると、キーワード検索なども可能です。
<?php
/**
* 検索フォーム.
*
* @package WordPress
*/
// 検索結果を表示している場合に検索条件を反映.
$selected_works_item = get_query_var( 'works_item' );
$selected_language = get_query_var( 'language' );
$selected_tool = get_query_var( 'tool' );
?>
<form role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<!-- input・selectタグなど -->
<?php
$works_item = get_terms( 'works_item' );
if ( ! empty( $works_item ) ) :
?>
<?php foreach ( $works_item as $item ) : ?>
<label for="<?php echo esc_attr( $item->slug ); ?>">
<input type="checkbox" name="works_item[]" id="<?php echo esc_attr( $item->slug ); ?>" value="<?php echo esc_attr( $item->slug ); ?>"
<?php
if ( ! empty( $selected_works_item ) ) {
echo in_array( $item->slug, $selected_works_item, true ) ? 'checked' : '';
}
?>
>
<?php echo esc_html( $item->name ); ?>
</label>
<?php endforeach; ?>
<?php endif; ?>
<!-- / input・selectタグなど -->
<input type="hidden" name="s" value="" /><!-- 検索結果のテンプレートを表示させるために必要 -->
<button lang="en" type="submit" id="searchsubmit">検索</button>
</form>
全件表示時のテンプレートを作る
全件表示時に使用するファイルを作ります。
searchform.phpを読み込んで、ループを書いたら完成です。
<?php
if( have_posts() ) {
get_template_part( 'searchform' ); // 検索フォームを読み込み.
while( have_posts() ) {
the_post();
// 記事へのリンクなど.
}
}
?>
検索結果を表示する
archive.phpを複製して名前を「search.php」に変更します。 ループ部分を下記のコードで置き換えます。
検索条件はWP_Queryのオプションを変更することで、設定できます。
通常のキーワード検索と絞り込み検索を利用する場合は、特定のクエリ変数が存在するかなどで、処理内容を切り替えると良いと思います。(少し雑な気もしますが)
<?php
$now_page = get_query_var( 'paged' ) ?: 1; // 現在のページが1ページ目かそれ以外かを取得.
// 検索条件を取得.
$works_item = get_query_var( 'works_item' );
$language = get_query_var( 'language' );
$tool = get_query_var( 'tool' );
?>
<?php get_template_part( 'include/searchform' ); // 検索フォームを読み込み. ?>
<?php
$args = array(
'post_type' => 'works', // 絞り込み検索をする投稿タイプ.
'paged' => $now_page, // 何ページ目の記事を取得するか.
'posts_per_page' => 10, // 1ページに表示する記事数.
'tax_query' => array( // 検索条件.
'relation' => 'AND',
),
);
// 検索条件を追加.
if ( ! empty( $works_item ) ) {
$args['tax_query'][] = array(
'taxonomy' => 'works_item',
'field' => 'slug',
'terms' => $works_item,
'operator' => 'IN',
);
}
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) :
$the_query->the_post();
// 記事へのリンク.
endwhile;
else :
?>
<p>
条件に当てはまる制作実績は見つかりませんでした。
</p>
<?php
endif;
wp_reset_postdata();
?>
まとめ
プラグインを使わずに絞り込み検索のフォームを作ると、タグやclassを自由に変更できて良いですね。