【WordPress】カスタムタクソノミーの絞り込み検索で効率的に$_GETを取得する
WordPressのお仕事で個人的によく対応するものの中に「カスタムタクソノミーを使った絞り込み検索」の実装があります。
今回は、サンプルケースを交えながらカスタムタクソノミーを利用した検索フォームからの$_GETの値を効率的に取得する方法についてご紹介したいと思います。
今回のケース
観光地の絞り込み検索機能の実装を例として考えたいと思います。
検索フォームとしては
エリア・観光地タイプを選択して、こだわりポイントにチェックを付けて検索…というものです。
WordPress側では
sightseeing(カスタム投稿タイプ:観光地)
-area(カスタムタクソノミー:地方名)
--hokkaido(地方名のターム)
--tohoku
--kanto
…
-spot-type(カスタムタクソノミー:観光地タイプ)
--onsen(観光地タイプのターム)
--shopping
--food
…
-point(カスタムタクソノミー:こだわりポイント)
--popular(こだわりポイントのターム)
--family
--reserve
…
上記のような感じで観光地情報の投稿をarea・spot-type・pointで分類しているという想定です。
今回はフリーワード検索はなし、検索結果は固定ページを利用することにします。
予め、WordPressの固定ページでパーマリンクがsearch-resultとした検索結果ページを、そのテンプレートファイルとしてpage-search-result.phpを順次作成します。
検索フォームを作る
まず、検索フォームを見てみましょう。formタグ内に絞って書いてみると…
<form id="search" method="get" action="<?= esc_url(home_url('search-result')); ?>">
<p>エリア</p>
<?php get_search_terms( 'area' ); ?>
<p>タイプ</p>
<?php get_search_terms( 'spot-type' ); ?>
<p>こだわりポイント</p>
<?php get_search_terms( 'point' ); ?>
<button type="submit" form="search">検索する</button>
</form>
タクソノミースラッグを引数としているget_search_termsで入力部分を生成
↓
検索ボタンを押すと、search-resultのパーマリンクを持つ検索結果用の固定ページに内容を送信
こんな流れです。
functions.phpでget_search_termsの処理を書いていきます。
function get_search_terms( $taxonomy ) {
$html = '';
// 引数のタクソノミーに登録されているターム取得
$terms = get_terms( [
'taxonomy' => $taxonomy,
] );
if ( $taxonomy === 'point' ) { // こだわりポイントはcheckbox
$html .= '<div">';
foreach ( $terms as $term ) {
$html .= '<div class="search__check">';
$html .= '<input type="checkbox" id="' . esc_attr($term->slug) . '" name="' . esc_attr($taxonomy) . '[]" value="' . esc_attr($term->slug) . '">';
$html .= '<label for="' . esc_attr($term->slug) . '">' . esc_html($term->name) . '</label></div>';
}
$html .= '</div>';
}
else { // それ以外はselect
$html .= '<select name="' . esc_attr($taxonomy) . '" id="' . esc_attr($taxonomy) . '">';
foreach ( $terms as $term ) {
$html .= '<option value="' . esc_attr($term->slug) . '">' . esc_html($term->name) . '</option>';
}
$html .= '</select>';
}
echo $html;
}
get_termsで渡された引数のタクソノミーのタームを全て取得していますが、条件でhide_emptyをfalseとする内容を加えると、投稿のないタームでも表示ができます。
渡された引数に応じてcheckboxとselectを切り替えて$htmlに格納
↓
$htmlをechoする
という流れです。
各入力パーツのname属性はタクソノミースラッグにして、チェックボックスなど複数の選択ができるものはname属性の値の最後に角括弧[]を入れて配列でデータを送信できるようにしましょう。
検索結果ページでの$_GETの受取
それでは本題へ。
page-search-result.phpのget_header();の下にまずは以下の記述を書いていきます。
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// $_GET取得用
$tax_array = get_search_tax_array();
// 検索用条件の取得
$args = get_search_args($tax_array, $paged);
// 検索用クエリ
$wp_query = new WP_Query($args);
get_search_tax_arrayで$_GETにある送信内容取得を行う
↓
タクソノミー毎の送信内容を配列として変数に格納
↓
その変数とページネーション用のpagedを引数にするget_search_argsで検索用の条件を取得する
こういった流れです。
今回のミソであるget_search_tax_array関数を書いていきます。
// 検索に使用するタクソノミーを取得する
function get_search_tax_array() {
$tax_args = [
'public' => true,
'_builtin' => false,
];
$taxonomies = get_taxonomies($tax_args);
// GETで存在するタクソノミーを連想配列に格納
// 検索タクソノミー配列
$tax_array = [];
foreach ($taxonomies as $taxonomy) {
if ( !empty($_GET[$taxonomy]) ) {
$tax_array[$taxonomy] = $_GET[$taxonomy];
}
}
return $tax_array;
ポイントはget_taxonomiesで全タクソノミーを取得→foreachで$_GETの中にタクソノミー名のnameから送られたものがあれば検索用タクソノミー配列とするという処理をすることです。
わざわざGETの中身を['area']などと直接書かずに、送信内容のあるタクソノミー名のnameに合致する情報をそのまま取得してくれます。
しかも検索用のタクソノミーが増えた時にも対応できます。
WP_Query用の検索条件の取得
続いて、functions.phpでget_search_argsの処理を書きます。
function get_search_args($array, $paged) {
$args = [
'post_type' => 'sightseeing',
'post_status' => 'publish',
'orderby' => [
'date' => 'DESC',
'ID' => 'DESC'
],
'paged' => $paged,
];
// 検索項目の配列
$tax_query = [];
foreach ( $array as $key => $value ) {
$tax_query[] = [
'taxonomy' => $key,
'field' => 'slug',
'terms' => $value
];
}
if ( count($tax_query) > 0 ) {
$tax_query['relation'] = 'AND';
$args += ['tax_query' => $tax_query];
}
return $args;
}
引数として渡された$tax_arrayを使って、タクソノミー毎にtax_queryを増やす記述をしています。
こだわりポイントのチェックボックスから複数の値がチェックされて送られた際も、$valueは配列としてデータを持っています。
[
[0] => 'popular',
[1] => 'reserve'
]
そのため、そのままtax_queryのtermsに入れてあげる形でOKです。
後は、この関数で取得した$argsを使ってWP_Queryでサブループを回して検索結果を出力できる、というのが一連の流れです。
今回のポイント
- 検索フォームで各入力パーツのname属性にタクソノミースラッグを入れる
- get_taxonomiesで全てのタクソノミー情報を取得
- その後、GETが空でなければ$tax_arrayにタクソノミースラッグをキーとしてGETの各タクソノミースラッグの入力値を全タクソノミーのforeachを使って取得する
いかがでしたでしょうか?
WordPressでの絞り込み検索の自作の際に活用して頂けましたら嬉しい限りです。
Discussion