先日、カスタムタクソノミーのタームとキーワードによる複合検索に非常に苦労しました。調べても自分にマッチした記事がなかなか無くて、今回誰かの参考になればと思い備忘録としてまとめます。
- カスタム投稿タイプ名を test とする。
- タクソノミースラッグ名を test_cat とする。
まず理解しておきたいこと
複合検索フォームで必要なものは以下の通り。
- 検索フォーム
- 検索結果を表示するsearch.php
検索フォームを入力してその入力した内容を検索結果として反映させるsearch.phpのファイルが必要になります。当たり前だけど、意外と迷いがち…だと思う。
投稿タイプごとの検索フォームを作成
ページ規模が大きくなってくると複数の検索フォームが必要になることもあります。その場合は、functions.phpで固有のphpファイルを認識させましょう。
以下のコードをfunctions.phpに記述すれば、カスタム投稿タイプに属した検索フォームが認識されるようになります。
add_filter('template_include','custom_search_template');
function custom_search_template($template){
if ( is_search() ){
$post_types = get_query_var('post_type');
foreach ( (array) $post_types as $post_type )
$templates[] = "search-{$post_type}.php";
$templates[] = 'search.php';
$template = get_query_template('search',$templates);
}
return $template;
}
今回の場合はsearch-test.phpという個別のphpファイルを作成しておきましょう。
検索フォームの作成
検索フォームのコードは以下の通りです。
<div class="search-form">
<form method="get" action="<?php bloginfo( 'url' ); ?>">
<?php
$selected = get_query_var("test_cat",0);
$args = array(
'show_option_all' => 'カテゴリ選択',
'taxonomy' => 'test_cat',
'name' => 'test_cat',
'value_field' => 'slug',
'hide_empty' => 1,
'selected' => $selected
);
wp_dropdown_categories($args);
?>
<input type="hidden" name="post_type" value="test">
<input type="text" name="s" id="s" value="<?php echo get_search_query(); ?>" placeholder="キーワードを入力">
<input type="submit" value="検索">
</form>
以下、解説付きです。
<div class="search-form">
<form method="get" action="<?php bloginfo( 'url' ); ?>">
//そのままでOK
<?php
$selected = get_query_var("test_cat",0);
//タクソノミースラッグ名
$args = array(
'show_option_all' => 'カテゴリ選択',
//何も選択されていないときの初期表示名
'taxonomy' => 'test_cat',
'name' => 'test_cat',
//タクソノミースラッグ名
'value_field' => 'slug',
'hide_empty' => 1,
'selected' => $selected
//この辺はそのままで
);
wp_dropdown_categories($args);
//上で設定した内容をwp_dropdown_categoriesで取得
?>
<input type="hidden" name="post_type" value="test">
<input type="text" name="s" id="s" value="<?php echo get_search_query(); ?>" placeholder="キーワードを入力">
//ここはキーワード検索の窓
<input type="submit" value="検索">
</form>
wp dropdown categoriesについてはCodexにて確認してください。
ここまで設定できれば検索フォームが完成しているはずです。ドロップダウンリストを開くと作成したターム名が選べるようになっているはず。
CSSによるデザインは行っていないので、各自で調整してください。
検索結果を表示する機能を実装
あとは検索結果を表示するために先程作ったsearch-test.phpを編集していきます。
まずは検索フォームで入力された内容を整理します。以下のように各変数に格納しましょう。
<?php
$posy_type = htmlspecialchars($_GET['post_type'], ENT_QUOTES);
//検索フォームで入力したここの情報 → <input type="hidden" name="post_type" value="test">
$search_query = get_search_query();
//検索フォームに入力されたキーワード情報を取得
$cat = htmlspecialchars($_GET['test_cat'], ENT_QUOTES);
//ドロップダウンリストから選択された情報を取得
?>
上記の情報をもとにサブループで表示するのが検索結果ページ作成の流れです。
まずはベースとなるサブループの条件を作ります。
$args=array(
'post_type'=> $post_type, //投稿タイプ
'post_status' => 'publish',//公開ページのみ
'posts_per_page' => '15',//表示記事数
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
);
次に条件分岐で「検索キーワードが空白ではない場合」の条件を記述。
if (!empty($search_query)) {//検索キーワードが空白ではない場合
$args += array('s' => $search_query);//sにキーワードをセット
}
「 += 」で条件が合致したときに$argsに追加出来ます。
また、$cat(プルダウンの選択された値)も追加しましょう
if (!empty($cat)) {
$args += array(
'tax_query' => array(
array(
'taxonomy' => 'test_cat',//タクソノミー名
'field' => 'slug',
'terms' => $cat,//スラッグ名
)
)
);
上記の条件分岐を使うと、
- キーワードが空白かそうでないか
- タームが選択されているかそうでないか
の使い分けが可能です。
$the_query = new WP_Query($args);
$total_results = $the_query->found_posts;//検索結果の総数
$term_name = get_term_by('slug',$cat,'test_cat')->name;//タームslugから日本語の名前に変換
ここまでくればあとはいつもどおりサブループで記載してくれれば大丈夫なのですが、せっかくなので検索結果表示の条件分岐についても触れていきます
検索結果毎に表示する内容を変える実装
タームと検索キーワードの複合検索では主に以下の4つに分けられます。
- カテゴリ指定無し、キーワード入力無し
- カテゴリ指定有り、キーワード入力無し
- カテゴリ指定無し、キーワード入力有り
- カテゴリ指定有り、キーワード入力有り
検索条件をタイトルに表示する場合はこれらも含めて分岐してあげないと、表示が崩れてしまいます
※もっとわかりやすい書き方あるかも。自分で書いてて分かりにくい…
<?php
if(empty($search_query) && empty($cat)):
//カテゴリ指定無し、キーワード入力無しの場合の内容
else:
//カテゴリ指定有り、キーワード入力有りの場合を以下に記述してます
if(!empty($search_query) || !empty($cat)){
//検索結果を表示する機能を実装の部分に記述した条件分岐
$args=array( 'post_type'=> 'affiliated_discount',
'post_status' => 'publish',
'posts_per_page' => '15',
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
);
} //if(!empty($search_query) || !empty($cat))
if (!empty($search_query)) {
//検索キーワードが空でない場合、以下の条件をargsに追加
$args += array('s' => $search_query);
} //if (!empty($search_query))
if (!empty($cat)) {
//ターム指定が空でない場合、以下の条件をargsに追加
$args += array(
'tax_query' => array(
array(
'taxonomy' => 'affiliated_discount_cat',
'field' => 'slug',
'terms' => $cat,
)
)
);
} //if (!empty($cat))
$the_query = new WP_Query($args);
$total_results = $the_query->found_posts;
$term_name = get_term_by('slug',$cat,'affiliated_discount_cat')->name;
if( $total_results >0 ): //以下、検索ターム、検索キーワードをタイトル表示
if (empty($s)): //キーワードが空白の場合
if (!empty($cat))://タームが指定されている場合(キーワード無し&タームが選択有り)
echo $term_name;//ターム名表示
echo $total_results;//検索結果数の表示
endif; //if (empty($cat))
else: //if (empty($s))
if (!empty($cat)): //タームが指定されている場合
echo $term_name; //ターム名表示
echo $search_query; //検索キーワード表示
echo $total_results; //検索結果表示
else: //if (!empty($cat)): //タームが指定されていない場合
echo $search_query; //検索キーワード表示
echo $total_results; //検索結果表示
endif; //if (empty($cat))
endif; //if (empty($s))
//サブループ開始
if( $the_query->have_posts() ) : while( $the_query->have_posts() ) : $the_query->the_post();
ループする内容
endwhile; endif; wp_reset_postdata();
else: //if( $total_results >0 )※検索に合致する条件がなかったとき
if (empty($s)): //キーワードが空白の場合
if (!empty($cat)): //タームが選択されていた場合
echo $term_name;. '一致する情報は見つかりませんでした' //タームに一致する情報が無かった
endif; //if (empty($cat))
else: //if (empty($s)) キーワードが空白ではない場合
if (!empty($cat)): //タームが選択されていた場合
echo $term_name;
echo $search_query .'一致する情報は見つかりませんでした';
else: //if (!empty($cat)): //タームが選択されていなかった場合
echo $search_query .'一致する情報は見つかりませんでした'; //検索キーワードに一致する情報なし
endif;
endif; //if (empty($s))
endif;//if( $total_results >0 ):
endif; //if(empty($search_query) && empty($cat))
?>
こんな感じで4つの検索パターンに対応できます。
なおこれらのコードはコピペでは間違いなくエラーでるのでうまく修正して使って下さい。
まとめ
複合検索の書き方をまとめます
- 検索フォームの実装
- 検索結果をsearch.phpで表示
- 検索結果を条件に追加してサブループで表示
表示させる際はif〜elseじゃなくてifだけで分岐してった方がわかりやすいですね。
同じ実装する機会があれば書き直します。
コメント