この記事はCMS(WordPressやヘッドレスCMS) Advent Calendar 2023の15日目の記事です。
空きがあったので参加させていただきました。
はじめに
あまたあるWordPress
のプラグインの中でもCustom Post Type UI
は超有名ですよね。最近WordPress
については運用・保守作業ばかりで、サイト制作は全然なのですが制作時はよくお世話になりました。
数年前の話になりますが、新規WordPress
サイトの制作でクライアント(社内グループ各社)の要望に検索機能がありました。しかし予算の都合上、有料プラグインは使用できなそうだったので自作することになったのです。
今回、その時に制作した「カスタム投稿タイプとタクソノミー」を用いた検索機能について書いていこうと思います。
筆者が自ら集めた情報をつなぎ合わせる形で自作したため、エスケープ処理などセキュリティには気を配ってはいますが、正直開発者体験(DX)は悪い作りになっていると思います。
まずもって、大規模で複雑な検索機能を作るには向いていないと思いますので、そういったものをお求めの方は他の優良な情報を探すか、有料プラグインの導入をご検討ください。
ファイル構成(テーマ内での使用想定)
|---searchpart
|--- part-filtersearch.php
|--- search.php
|--- functions.php
-
searchpart/part-filtersearch.php
検索項目用のテンプレートパーツファイル -
search.php
検索結果ページ。part-filtersearch.php
内で処理される配列(各検索項目の内容が格納された箱)から渡ってきた検索項目を取得し、WP_Query
(とtaxQuery
)を使ってコンテンツを表示。ページャーはthe_posts_pagination
を使用。 -
functions.php
絞り込み検索機能に関する記述(DBからのデータ取得)など
検索項目用のテンプレートパーツファイル
part-filtersearch.php
では検索項目を整えて、検索結果ページsearch.php
に渡すためのデータセットを用意します。
WordPress
で検索機能を実装する際form
要素のaction
属性に以下の記述が必要なので注意してください。
action="<?php echo esc_url(home_url('/'))"
蛇足ですが、キーワード検索の場合はinput
要素のname
属性とid
属性にs
という記述が必要です。
<input type="text" value="<?php echo esc_attr( get_search_query() ); ?>" name="s" id="s">
<form role="search" method="get" id="searchform" class="searchform" action="<?php echo esc_url(home_url('/')); // 検索機能に記述必須 ?>">
:
:
<div class="selectschoolWrapper">
<p>項目タイトル</p>
<?php
$ConstSearchTargets = [
// 'order' => 'DESC', // 'ASC'(昇順), 'DESC'(降順),【初期値】'ASC'
'value_field' => 'slug', // (フォームの)option要素の'value'属性へ入れるタームのフィールド(現状スラッグ)
'taxonomy' => 'taxonomy_name', // タクソノミー名
'name' => 'get_searches[]', // 当該検索項目を格納する配列
'id' => 'echoIdAttr', // 要素へ付与するid属性名を記述。初期値だと'name'に指定した内容になる
// 'show_option_none' => ('以下から選択'), // 初期プレースホルダー
'option_none_value' => '', // 未選択時のoption要素のvalue属性値を指定(空 = %5B%5D = [])
'exclude' => [240, 273], // 'tag_id=xxxx'のタームを除外
];
?>
<?php wp_dropdown_categories( $ConstSearchTargets ); // ドロップダウンメニューで変数($ConstSearchTargets)の内容を出力 ?>
</div>
ここではドロップダウンリスト(wp_dropdown_categories
)を使用しています。
連想配列で指定している'name' => 'get_searches[]'
が検索結果ページ(search.php
)に渡す(配列)データになります。
- 検索項目を選択する第一セクションを用意
例として「対象地域・エリア」とします。こちらはチェックボックス(input type="checkbox"
)を使用しています。
input
要素に指定しているname="get_searcharea[]"
が検索結果ページ(search.php
)に渡す(配列)データになります。
<div class="areaWrapper">
<p>対象地域・エリアを選択</p>
<details class="SearchMenu" id="AreaBox">
<summary>エリア</summary>
<?php
$term_id = 163; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'search_area'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<!-- name属性:項目内容を格納する配列(name="xxxx[]")を用意(*ここで指定した配列の中身(ユーザーがチェックした選択項目)をsearch.php(検索結果ページ)で呼び出す)
value属性:タームスラッグを呼び出す(value="?php echo esc_attr( $term->slug ); ?
ターム名を表示:?php echo esc_html( $term->name) ; ?
-->
<summary><label><input type="checkbox" name="get_searcharea[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
</div>
- 検索項目を選択する第二セクションを用意
例として「ジャンル」とします。こちらもチェックボックスを使用しています。
第一セクションと同じく、input
要素に指定しているname
属性の値が検索結果ページ(search.php
)に渡す(配列)データになります。
<div id="MajorBox">
<p>ジャンルを選択</p>
<details class="children">
<summary>ジャンル[A]</summary>
<details>
<summary>ジャンル[A-1]</summary>
<?php
$term_id = 165; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunkei'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunkei01[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
<details>
<summary>ジャンル[A-2]</summary>
<?php
$term_id = 166; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunkei'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunkei02[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
<details>
<summary>ジャンル[A-3]</summary>
<?php
$term_id = 184; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunkei'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunkei03[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
</details>
<details class="children">
<summary>ジャンル[B]</summary>
<details>
<summary>ジャンル[B-1]</summary>
<?php
$term_id = 178; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunri'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunri01[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
<details>
<summary>ジャンル[B-2]</summary>
<?php
$term_id = 194; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunri'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunri02[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
</details>
<details class="children">
:
:
</div>
- キーワード検索と検索実行ボタンを用意
<div class="get_search">
<label><input type="search" placeholder="フリーワードを入力" value="" name="s" id="s"></label>
</div>
<input type="hidden" name="post_type" value="CustomPostType_SlugName">
<p id="department_btn"><input type="submit" value="検索"></p>
input type="hidden"
は記述が必要なので忘れないように注意してください。
データ取得対象のカスタム投稿タイプが複数ある場合は、
<input type="hidden" name="投稿タイプ" value="カスタム投稿タイプ(のスラッグ)名">
上記の形で取得する数を用意してください。以下に例を置いておきます。
<input type="hidden" name="post_type_hoge" value="CustomPostType_Hoge_SlugName">
<input type="hidden" name="post_type_foo" value="CustomPostType_Foo_SlugName">
最後に蛇足ですが、検索結果ページ(search.php
)で検索キーワードをプレースホルダーに表示したい場合は下記を記述してください。
<input type="hidden" value="<?php echo esc_attr(get_search_query()); ?>" name="s" id="s">
これで、part-filtersearch.php
の記述は終了です。以下にコード全文を記載しておきます。
part-filtersearch.php のコード全文
<div class="department_wrapper">
<div class="SearchWrapper">
<div id="SearchMainWrapper">
<h3>タイトル</h3>
<div class="selectschoolWrapper">
<p>項目タイトル</p>
<?php
$ConstSearchTargets = [
// 'order' => 'DESC', // 'ASC'(昇順), 'DESC'(降順),【初期値】'ASC'
'value_field' => 'slug', // (フォームの)option要素の'value'属性へ入れるタームのフィールド(現状スラッグ)
'taxonomy' => 'taxonomy_name', // タクソノミー名
'name' => 'get_searches[]', // 当該検索項目を格納する配列
'id' => 'echoIdAttr', // 要素へ付与するid属性名を記述。初期値だと'name'に指定した内容になる
// 'show_option_none' => ('以下から選択'), // 初期プレースホルダー
'option_none_value' => '', // 未選択時のoption要素のvalue属性値を指定(空 = %5B%5D = [])
'exclude' => [240, 273], // 'tag_id=xxxx'のタームを除外
];
?>
<?php wp_dropdown_categories($ConstSearchTargets); // ドロップダウンメニューで変数($ConstSearchTargets)の内容を出力
?>
</div>
<div class="areaWrapper">
<p>対象地域・エリアを選択</p>
<details class="SearchMenu" id="AreaBox">
<summary>エリア</summary>
<?php
$term_id = 163; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'search_area'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<!-- name属性:項目内容を格納する配列(name="xxxx[]")を用意(*ここで指定した配列の中身(ユーザーがチェックした選択項目)をsearch.php(検索結果ページ)で呼び出す)
value属性:タームスラッグを呼び出す(value="?php echo esc_attr( $term->slug ); ?
ターム名を表示:?php echo esc_html( $term->name) ; ?
-->
<summary><label><input type="checkbox" name="get_searcharea[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
</div>
<div id="MajorBox">
<p>ジャンルを選択</p>
<details class="children">
<summary>ジャンル[A]</summary>
<details>
<summary>ジャンル[A-1]</summary>
<?php
$term_id = 165; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunkei'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunkei01[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
<details>
<summary>ジャンル[A-2]</summary>
<?php
$term_id = 166; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunkei'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunkei02[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
<details>
<summary>ジャンル[A-3]</summary>
<?php
$term_id = 184; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunkei'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunkei03[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
</details>
<details class="children">
<summary>ジャンル[B]</summary>
<details>
<summary>ジャンル[B-1]</summary>
<?php
$term_id = 178; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunri'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunri01[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
<details>
<summary>ジャンル[B-2]</summary>
<?php
$term_id = 194; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'bunri'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_bunri02[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
</details>
<details class="children">
<summary>ジャンル[C]</summary>
<details>
<summary>ジャンル[C-1]</summary>
<?php
$term_id = 180; // tag_id=xxxx:タグID(数値)を指定
$taxonomy_name = 'rikei'; // taxonomy=xxxx:タクソノミーSlug(文字列)を指定
$termchildren = get_term_children($term_id, $taxonomy_name);
foreach ($termchildren as $child) :
$term = get_term_by('id', $child, $taxonomy_name);
?>
<summary><label><input type="checkbox" name="get_rikei01[]" value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></label></summary>
<?php endforeach; ?>
</details>
</details>
</div>
</div>
<div class="get_search">
<label><input type="search" placeholder="フリーワードを入力" value="" name="s" id="s"></label>
</div>
<input type="hidden" name="post_type" value="CustomPostType_SlugName">
<p id="department_btn"><input type="submit" value="検索"></p>
</div>
</div>
検索結果ページ
search.php
では、part-filtersearch.php
から渡ってきた「検索項目データ(連想配列やname
属性の値で指定していた配列データ)」を取得し、WP_Query
(とtaxQuery
)を使ってコンテンツを表示しています。
以下の記述からは、筆者のPHP
に関する知識不足が原因で冗長な記述になっており、申し訳なく思います。正直もっとスマートな記述があるはずです。
- はじめに取得するデータを格納する場所を作ってあげます。
条件分岐で!isset
で変数の中身をチェックして何も無い場合、または変数が空の場合に当該変数にnull
を代入しています。これはWordPress
のdebugMode: true
時に注意されたので、その応急処置になります。上記条件にあてはまらない場合(else
時)は当該変数に所定のデータを代入しています。
if (!isset($_GET['get_Hoge']) || $_GET['get_Hoge'] === '') {
// !isset で変数の中身をチェックして何も無い場合、または変数が空の場合に当該変数に null を代入
$get_Hoge = null;
}
else {
// 当該変数に所定のデータを代入
$get_Hoge = $_GET['get_Hoge'];
}
長いのでコード全文はこちらから
<?php
// キーワード
$s = $_GET['s'];
// ドロップダウンリストの項目
if (!isset($_GET['get_searches']) || $_GET['get_searches'] === '') {
$get_searches = null;
} else {
$get_searches = $_GET['get_searches'];
}
// エリア
if (!isset($_GET['get_searcharea']) || $_GET['get_searcharea'] === '') {
$get_searcharea = null;
} else {
$get_searcharea = $_GET['get_searcharea'];
}
// ジャンル
if (!isset($_GET['get_bunkei01']) || $_GET['get_bunkei01'] === '') {
$get_bunkei01 = null;
} else {
$get_bunkei01 = $_GET['get_bunkei01'];
}
if (!isset($_GET['get_bunkei02']) || $_GET['get_bunkei02'] === '') {
$get_bunkei02 = null;
} else {
$get_bunkei02 = $_GET['get_bunkei02'];
}
if (!isset($_GET['get_bunkei03']) || $_GET['get_bunkei03'] === '') {
$get_bunkei03 = null;
} else {
$get_bunkei03 = $_GET['get_bunkei03'];
}
if (!isset($_GET['get_bunri01']) || $_GET['get_bunri01'] === '') {
$get_bunri01 = null;
} else {
$get_bunri01 = $_GET['get_bunri01'];
}
if (!isset($_GET['get_bunri02']) || $_GET['get_bunri02'] === '') {
$get_bunri02 = null;
} else {
$get_bunri02 = $_GET['get_bunri02'];
}
if (!isset($_GET['get_rikei01']) || $_GET['get_rikei01'] === '') {
$get_rikei01 = null;
} else {
$get_rikei01 = $_GET['get_rikei01'];
}
// ジャンルをまとめた変数(get_major)
if ($get_bunkei01 || $get_bunkei02 || $get_bunkei03 || $get_bunri01 || $get_bunri02 || $get_rikei01) {
$get_major = [
$get_bunkei01,
$get_bunkei02,
$get_bunkei03,
$get_bunri01,
$get_bunri02,
$get_rikei01
];
} else {
$get_major = null;
}
// 検索用データ(キーワード、ドロップダウンリストの項目、エリア項目、ジャンル項目)をまとめた変数(get_cats)
$get_cats = [
$s,
$get_searches,
$get_searcharea,
$get_major
];
// タクソノミーデータ(ドロップダウンリストの項目)
$tax_TargetTaxonomy = [
'taxonomy' => 'taxonomy_name',
'field' => 'slug',
'terms' => $get_searches,
'operator' => 'IN',
];
// タクソノミーデータ(エリア項目)
$tax_searcharea = [
'taxonomy' => 'search_area',
'field' => 'slug',
'terms' => $get_searcharea,
'operator' => 'IN',
];
// タクソノミーデータ(ジャンルの項目に内包される各タクソノミー)
$tax_bnk01 = [
'taxonomy' => 'bunkei',
'field' => 'slug',
'terms' => $get_bunkei01,
'operator' => 'IN',
];
$tax_bnk02 = [
'taxonomy' => 'bunkei',
'field' => 'slug',
'terms' => $get_bunkei02,
'operator' => 'IN',
];
$tax_bnk03 = [
'taxonomy' => 'bunkei',
'field' => 'slug',
'terms' => $get_bunkei03,
'operator' => 'IN',
];
$tax_bunri01 = [
'taxonomy' => 'bunri',
'field' => 'slug',
'terms' => $get_bunri01,
'operator' => 'IN',
];
$tax_bunri02 = [
'taxonomy' => 'bunri',
'field' => 'slug',
'terms' => $get_bunri02,
'operator' => 'IN',
];
$tax_rk01 = [
'taxonomy' => 'rikei',
'field' => 'slug',
'terms' => $get_rikei01,
'operator' => 'IN',
];
?>
- 次に、必要に応じて条件分岐を行っておきます。
// CustomPostType_SlugName の一覧ページで、かつ get_cats 変数(検索用データ:キーワード、ドロップダウンリストの項目、エリア項目、ジャンル項目をまとめた変数)に各引数の変数(の中身)がどれか一つでも存在する場合
<?php if (
is_post_type_archive('CustomPostType_SlugName') &&
$get_cats = isset($s) || isset($get_searches) || isset($get_searcharea) || isset($get_major)) :
?>
- 検索キーワード・項目や検索結果件数を表示したい場合
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
[
$tax_searcharea,
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
上記の一例を説明しますと、サブループ(WP_Query
)を用いてドロップダウンリストの項目($tax_TargetTaxonomy
)とエリア($tax_searcharea
)、ジャンルの項目(tax_query
の連想配列内の3つ目の配列内容)から、指定したカスタム投稿タイプ(Target_PostTypeName
)内で該当するコンテンツデータを取得します。
各タクソノミーはAND
検索条件ですが、ジャンル項目の中身のみOR
検索条件にしています。
そして、そのデータからコンテンツ数を取得して表示しています。
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
これらを以下のコードのように、条件ごとに随時指定していく形です……。
つまり、検索項目が増えるたびに以下の作業を行う必要があるので大規模または複雑な仕様には向いていないと思います。
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : ?>
<!-- キーワード + ドロップダウンリストの項目(エリア項目とジャンル項目は無し) -->
:
:
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && isset($get_major)) : ?>
<!-- ドロップダウンリストの項目とエリア項目とジャンル項目(キーワードは無し) -->
:
:
<?php elseif ($get_cats = isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : ?>
<!-- ドロップダウンリストの項目とジャンル項目(エリア項目は無し) -->
:
:
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && !isset($get_major)) : ?>
<!-- ドロップダウンリストの項目とエリア項目(ジャンル項目は無し) -->
:
:
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : ?>
<!-- ジャンル項目のみ -->
:
:
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_major) && isset($get_searcharea)) : ?>
<!-- エリア項目のみ -->
:
:
<?php elseif ($get_cats = isset($get_searches) && !isset($get_major) && !isset($get_searcharea)) : ?>
<!-- ドロップダウンリストの項目のみ -->
:
:
// 条件ごとに随時指定していく……
<?php endif; ?>
検索ワードは以下の処理で表示しています。
<?php echo '<p id="array_word"><span>検索語句</span>';
if ($s) {
$key = esc_html($s, 1);
echo wp_kses_post('<small>フリーワード:' . $key . '</small>');
}
if ($get_searches) {
foreach ($get_searches as $val) {
$search_targetTaxType_term = get_term_by('slug', $val, 'taxonomy_name');
echo wp_kses_post('<small>' . $search_targetTaxType_term->name . '</small>');
}
}
if ($get_searcharea) {
foreach ($get_searcharea as $val) {
$search_area_term = get_term_by('slug', $val, 'search_area');
echo wp_kses_post('<small>' . $search_area_term->name . '</small>');
}
}
:
:
echo '</p>'; ?>
検索ワード取得・表示に関するコード全文はこちらから
<h2 class="search_h2">
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : // キーワード + ドロップダウンリストの項目(エリア項目とジャンル項目は無し)
?>
<?php
foreach ($get_searches as $val) {
$TaxonomyTypeSlug = get_term_by('slug', $val, 'taxonomy_name');
}
printf(__('検索結果 %s', 'altitude'), '<span id="SerachKeywords">' . htmlspecialchars($TaxonomyTypeSlug->name, ENT_QUOTES) . 'で、フリーワード:' . esc_html(get_search_query()) . '</span>'); ?>
<?php $allsearch = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]);
$key = esc_html($s, 1);
$count = $allsearch->post_count;
if ($count != 0 && !$get_cats) {
echo wp_kses_post('<p class="search_infotxt">"<strong>' . $key . '</strong>"で検索した結果、<strong>' . $count . '</strong>件ヒットしました。</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とエリア項目とジャンル項目(キーワードは無し)
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
[
$tax_searcharea,
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とジャンル項目(エリア項目は無し)
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && !isset($get_major)) : // ドロップダウンリストの項目とエリア項目(ジャンル項目は無し)
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
[
$tax_searcharea,
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ジャンル項目のみ
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_major) && isset($get_searcharea)) : // エリア項目のみ
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
[
'relation' => 'OR',
$tax_searcharea
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_major) && !isset($get_searcharea)) : // ドロップダウンリストの項目のみ
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
[
'relation' => 'OR',
$tax_TargetTaxonomy
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php endif; ?>
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : // キーワードが(1文字でも)存在する場合の件数表示用の条件分岐
?>
<?php $KeywordsAndTargetTaxNameType = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]);
$count = $KeywordsAndTargetTaxNameType->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt"><strong>' . $count . '</strong>件ヒットしました。</p>');
}
wp_reset_postdata();
?>
<?php else : ?>
<?php echo '<p id="array_word"><span>検索語句</span>';
if ($s) {
$key = esc_html($s, 1);
echo wp_kses_post('<small>フリーワード:' . $key . '</small>');
}
if ($get_searches) {
foreach ($get_searches as $val) {
$search_targetTaxType_term = get_term_by('slug', $val, 'taxonomy_name');
echo wp_kses_post('<small>' . $search_targetTaxType_term->name . '</small>');
}
}
if ($get_searcharea) {
foreach ($get_searcharea as $val) {
$search_area_term = get_term_by('slug', $val, 'search_area');
echo wp_kses_post('<small>' . $search_area_term->name . '</small>');
}
}
if ($get_bunkei01) {
foreach ($get_bunkei01 as $val) {
$args01_term = get_term_by('slug', $val, 'bunkei');
echo wp_kses_post('<small>' . $args01_term->name . '</small>');
}
}
if ($get_bunkei02) {
foreach ($get_bunkei02 as $val) {
$args02_term = get_term_by('slug', $val, 'bunkei');
echo wp_kses_post('<small>' . $args02_term->name . '</small>');
}
}
if ($get_bunkei03) {
foreach ($get_bunkei03 as $val) {
$args03_term = get_term_by('slug', $val, 'bunkei');
echo wp_kses_post('<small>' . $args03_term->name . '</small>');
}
}
if ($get_bunri01) {
foreach ($get_bunri01 as $val) {
$args04_term = get_term_by('slug', $val, 'bunri');
echo wp_kses_post('<small>' . $args04_term->name . '</small>');
}
}
if ($get_bunri02) {
foreach ($get_bunri02 as $val) {
$args05_term = get_term_by('slug', $val, 'bunri');
echo wp_kses_post('<small>' . $args05_term->name . '</small>');
}
}
if ($get_rikei01) {
foreach ($get_rikei01 as $val) {
$args06_term = get_term_by('slug', $val, 'rikei');
echo wp_kses_post('<small>' . $args06_term->name . '</small>');
}
}
echo '</p>'; ?>
<?php endif; ?>
</h2>
- コンテンツデータを取得及び表示
行っていることは至ってシンプルなループ処理です。
<?php if ($my_query->have_posts()) : ?>
<ul class="contents_list">
<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>
<li><!-- コンテンツの中身 --></li>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else : ?>
<li id="no_search_txt">
<h3>該当する項目・キーワードはございませんでした</h3>
</li>
</ul>
<?php endif; ?>
が、データの取得が面倒です。
先ほどの検索キーワード・項目や検索結果件数を表示する記述と重複する部分があるのですが、一部調整が必要になってきます。
<!-- 検索キーワード・項目や検索結果件数を表示する場合 -->
<?php
<?php $allsearch = new WP_Query([
'posts_per_page' => -1, // 全件取得
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]); ?>
<!-- コンテンツデータを表示する場合 -->
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; // ページ送り機能に記述必須
$my_query = new WP_Query([
'posts_per_page' => 6, // 表示件数を指定
'paged' => get_query_var('paged', 0), // ページ送り機能に記述必須
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]); ?>
たとえば、コンテンツデータでは表示件数を操作したかったのでposts_per_page
の値を指定しており、ページ送りに必要な記述を別途追記しています。以下は該当箇所の抜粋です。
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1;
:
:
'paged' => get_query_var('paged', 0),
そしてこれも検索キーワード・項目や検索結果件数を表示するのと同じく条件ごとに指定していきます……。
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : ?>
<!-- キーワード + ドロップダウンリストの項目(エリア項目とジャンル項目は無し) -->
:
:
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && isset($get_major)) : ?>
<!-- ドロップダウンリストの項目とエリア項目とジャンル項目(キーワードは無し) -->
:
:
<?php elseif ($get_cats = isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : ?>
<!-- ドロップダウンリストの項目とジャンル項目(エリア項目は無し) -->
:
:
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && !isset($get_major)) : ?>
<!-- ドロップダウンリストの項目とエリア項目(ジャンル項目は無し) -->
:
:
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : ?>
<!-- ジャンル項目のみ -->
:
:
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_major) && isset($get_searcharea)) : ?>
<!-- エリア項目のみ -->
:
:
<?php elseif ($get_cats = isset($get_searches) && !isset($get_major) && !isset($get_searcharea)) : ?>
<!-- ドロップダウンリストの項目のみ -->
:
:
// 条件ごとに随時指定していく……
<?php endif; ?>
コンテンツデータの取得及び表示に関するコード全文
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : // キーワード + ドロップダウンリストの項目(エリア項目とジャンル項目は無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とエリア項目とジャンル項目(キーワードは無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy
],
[
$tax_searcharea
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とジャンル項目(エリア項目は無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && !isset($get_major)) : // ドロップダウンリストの項目とエリア項目(ジャンル項目は無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy
],
[
$tax_searcharea
]
],
's' => $s,
]); ?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ジャンル項目のみ
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
's' => $s,
]); ?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_major) && isset($get_searcharea)) : // エリア項目のみ
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'OR',
$tax_searcharea
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_major) && !isset($get_searcharea)) : // ドロップダウンリストの項目のみ
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'OR',
$tax_TargetTaxonomy
],
's' => $s,
]); ?>
<?php endif; ?>
- ページ送り機能の実装
こうしてページャーを用意する準備が整いました。
ページャーはthe_posts_pagination
を使っています。
<?php if ($get_cats) : ?>
<div class="pn_link">
<?php the_posts_pagination([
'prev_text' => '←',
'next_text' => '→',
'total' => htmlspecialchars($my_query->max_num_pages, ENT_QUOTES) // $my_query(指定した変数を記入)
]); ?>
</div>
<?php endif; ?>
連想配列のtotal
にコンテンツデータを代入した変数(my_query
)を使用しています。ページ上限値を取得している箇所ですね。
'total' => htmlspecialchars($my_query->max_num_pages, ENT_QUOTES)
これで検索結果ページ(search.php
)の記述は終了です。以下にコード全文を記載しておきます。
search.php のコード全文
<?php get_header(); ?>
<?php
// キーワード
$s = $_GET['s'];
// ドロップダウンリストの項目
if (!isset($_GET['get_searches']) || $_GET['get_searches'] === '') {
$get_searches = null;
} else {
$get_searches = $_GET['get_searches'];
}
// エリア
if (!isset($_GET['get_searcharea']) || $_GET['get_searcharea'] === '') {
$get_searcharea = null;
} else {
$get_searcharea = $_GET['get_searcharea'];
}
// ジャンル
if (!isset($_GET['get_bunkei01']) || $_GET['get_bunkei01'] === '') {
$get_bunkei01 = null;
} else {
$get_bunkei01 = $_GET['get_bunkei01'];
}
if (!isset($_GET['get_bunkei02']) || $_GET['get_bunkei02'] === '') {
$get_bunkei02 = null;
} else {
$get_bunkei02 = $_GET['get_bunkei02'];
}
if (!isset($_GET['get_bunkei03']) || $_GET['get_bunkei03'] === '') {
$get_bunkei03 = null;
} else {
$get_bunkei03 = $_GET['get_bunkei03'];
}
if (!isset($_GET['get_bunri01']) || $_GET['get_bunri01'] === '') {
$get_bunri01 = null;
} else {
$get_bunri01 = $_GET['get_bunri01'];
}
if (!isset($_GET['get_bunri02']) || $_GET['get_bunri02'] === '') {
$get_bunri02 = null;
} else {
$get_bunri02 = $_GET['get_bunri02'];
}
if (!isset($_GET['get_rikei01']) || $_GET['get_rikei01'] === '') {
$get_rikei01 = null;
} else {
$get_rikei01 = $_GET['get_rikei01'];
}
// ジャンルをまとめた変数(get_major)
if ($get_bunkei01 || $get_bunkei02 || $get_bunkei03 || $get_bunri01 || $get_bunri02 || $get_rikei01) {
$get_major = [
$get_bunkei01,
$get_bunkei02,
$get_bunkei03,
$get_bunri01,
$get_bunri02,
$get_rikei01
];
} else {
$get_major = null;
}
// 検索用データ(キーワード、ドロップダウンリストの項目、エリア項目、ジャンル項目)をまとめた変数(get_cats)
$get_cats = [
$s,
$get_searches,
$get_searcharea,
$get_major
];
// タクソノミーデータ(ドロップダウンリストの項目)
$tax_TargetTaxonomy = [
'taxonomy' => 'taxonomy_name',
'field' => 'slug',
'terms' => $get_searches,
'operator' => 'IN',
];
// タクソノミーデータ(エリア項目)
$tax_searcharea = [
'taxonomy' => 'search_area',
'field' => 'slug',
'terms' => $get_searcharea,
'operator' => 'IN',
];
// タクソノミーデータ(ジャンルの項目に内包される各タクソノミー)
$tax_bnk01 = [
'taxonomy' => 'bunkei',
'field' => 'slug',
'terms' => $get_bunkei01,
'operator' => 'IN',
];
$tax_bnk02 = [
'taxonomy' => 'bunkei',
'field' => 'slug',
'terms' => $get_bunkei02,
'operator' => 'IN',
];
$tax_bnk03 = [
'taxonomy' => 'bunkei',
'field' => 'slug',
'terms' => $get_bunkei03,
'operator' => 'IN',
];
$tax_bunri01 = [
'taxonomy' => 'bunri',
'field' => 'slug',
'terms' => $get_bunri01,
'operator' => 'IN',
];
$tax_bunri02 = [
'taxonomy' => 'bunri',
'field' => 'slug',
'terms' => $get_bunri02,
'operator' => 'IN',
];
$tax_rk01 = [
'taxonomy' => 'rikei',
'field' => 'slug',
'terms' => $get_rikei01,
'operator' => 'IN',
];
?>
<?php if (
is_post_type_archive('CustomPostType_SlugName') &&
$get_cats = isset($s) || isset($get_searches) || isset($get_searcharea) || isset($get_major)
) :
?>
<h2 class="search_h2">
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : // キーワード + ドロップダウンリストの項目(エリア項目とジャンル項目は無し)
?>
<?php
foreach ($get_searches as $val) {
$TaxonomyTypeSlug = get_term_by('slug', $val, 'taxonomy_name');
}
printf(__('検索結果 %s', 'altitude'), '<span id="SerachKeywords">' . htmlspecialchars($TaxonomyTypeSlug->name, ENT_QUOTES) . 'で、フリーワード:' . esc_html(get_search_query()) . '</span>'); ?>
<?php $allsearch = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]);
$key = esc_html($s, 1);
$count = $allsearch->post_count;
if ($count != 0 && !$get_cats) {
echo wp_kses_post('<p class="search_infotxt">"<strong>' . $key . '</strong>"で検索した結果、<strong>' . $count . '</strong>件ヒットしました。</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とエリア項目とジャンル項目(キーワードは無し)
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
[
$tax_searcharea,
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とジャンル項目(エリア項目は無し)
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && !isset($get_major)) : // ドロップダウンリストの項目とエリア項目(ジャンル項目は無し)
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
[
$tax_searcharea,
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ジャンル項目のみ
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_major) && isset($get_searcharea)) : // エリア項目のみ
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
[
'relation' => 'OR',
$tax_searcharea
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_major) && !isset($get_searcharea)) : // ドロップダウンリストの項目のみ
?>
<?php $all_search = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
[
'relation' => 'OR',
$tax_TargetTaxonomy
],
],
's' => $s,
]);
$count = $all_search->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt">該当件数:<strong>' . $count . '</strong>件</p>');
}
wp_reset_postdata();
?>
<?php endif; ?>
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : // キーワードが(1文字でも)存在する場合の件数表示用の条件分岐
?>
<?php $KeywordsAndTargetTaxNameType = new WP_Query([
'posts_per_page' => -1,
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]);
$count = $KeywordsAndTargetTaxNameType->post_count;
if ($count != 0) {
echo wp_kses_post('<p class="search_infotxt"><strong>' . $count . '</strong>件ヒットしました。</p>');
}
wp_reset_postdata();
?>
<?php else : ?>
<?php echo '<p id="array_word"><span>検索語句</span>';
if ($s) {
$key = esc_html($s, 1);
echo wp_kses_post('<small>フリーワード:' . $key . '</small>');
}
if ($get_searches) {
foreach ($get_searches as $val) {
$search_targetTaxType_term = get_term_by('slug', $val, 'taxonomy_name');
echo wp_kses_post('<small>' . $search_targetTaxType_term->name . '</small>');
}
}
if ($get_searcharea) {
foreach ($get_searcharea as $val) {
$search_area_term = get_term_by('slug', $val, 'search_area');
echo wp_kses_post('<small>' . $search_area_term->name . '</small>');
}
}
if ($get_bunkei01) {
foreach ($get_bunkei01 as $val) {
$args01_term = get_term_by('slug', $val, 'bunkei');
echo wp_kses_post('<small>' . $args01_term->name . '</small>');
}
}
if ($get_bunkei02) {
foreach ($get_bunkei02 as $val) {
$args02_term = get_term_by('slug', $val, 'bunkei');
echo wp_kses_post('<small>' . $args02_term->name . '</small>');
}
}
if ($get_bunkei03) {
foreach ($get_bunkei03 as $val) {
$args03_term = get_term_by('slug', $val, 'bunkei');
echo wp_kses_post('<small>' . $args03_term->name . '</small>');
}
}
if ($get_bunri01) {
foreach ($get_bunri01 as $val) {
$args04_term = get_term_by('slug', $val, 'bunri');
echo wp_kses_post('<small>' . $args04_term->name . '</small>');
}
}
if ($get_bunri02) {
foreach ($get_bunri02 as $val) {
$args05_term = get_term_by('slug', $val, 'bunri');
echo wp_kses_post('<small>' . $args05_term->name . '</small>');
}
}
if ($get_rikei01) {
foreach ($get_rikei01 as $val) {
$args06_term = get_term_by('slug', $val, 'rikei');
echo wp_kses_post('<small>' . $args06_term->name . '</small>');
}
}
echo '</p>'; ?>
<?php endif; ?>
</h2>
<?php if (get_search_query() && $get_cats = !isset($get_searcharea) && !isset($get_major) && isset($get_searches)) : // キーワード + ドロップダウンリストの項目(エリア項目とジャンル項目は無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy,
],
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とエリア項目とジャンル項目(キーワードは無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy
],
[
$tax_searcharea
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ドロップダウンリストの項目とジャンル項目(エリア項目は無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy
],
[
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && isset($get_searcharea) && !isset($get_major)) : // ドロップダウンリストの項目とエリア項目(ジャンル項目は無し)
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'AND',
[
$tax_TargetTaxonomy
],
[
$tax_searcharea
]
],
's' => $s,
]); ?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_searcharea) && isset($get_major)) : // ジャンル項目のみ
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'OR',
$tax_bnk01,
$tax_bnk02,
$tax_bnk03,
$tax_bunri01,
$tax_bunri02,
$tax_rk01
],
's' => $s,
]); ?>
<?php elseif ($get_cats = !isset($get_searches) && !isset($get_major) && isset($get_searcharea)) : // エリア項目のみ
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'OR',
$tax_searcharea
],
's' => $s,
]); ?>
<?php elseif ($get_cats = isset($get_searches) && !isset($get_major) && !isset($get_searcharea)) : // ドロップダウンリストの項目のみ
?>
<?php
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; //ページ送りの機能に必須
$my_query = new WP_Query([
'posts_per_page' => 6,
'paged' => get_query_var('paged', 0),
'post_type' => 'Target_PostTypeName',
'tax_query' => [
'relation' => 'OR',
$tax_TargetTaxonomy
],
's' => $s,
]); ?>
<?php endif; ?>
<main id="search_main">
<?php if ($my_query->have_posts()) : ?>
<ul class="contents_list">
<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>
<li><!-- コンテンツの中身 --></li>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else : ?>
<li id="no_search_txt">
<h3>該当する項目・キーワードはございませんでした</h3>
</li>
</ul>
<?php endif; ?>
<?php if ($get_cats) : ?>
<div class="pn_link">
<?php the_posts_pagination([
'prev_text' => '←',
'next_text' => '→',
'total' => htmlspecialchars($my_query->max_num_pages, ENT_QUOTES) // $my_query(指定した変数を記入)
]); ?>
</div>
<?php endif; ?>
</main>
<?php endif; ?>
<?php get_footer(); ?>
funcitons.php の設定
釈迦に説法かもですが、funcitons.php
は記述を誤るとサイトの機能・表示に支障をきたしますので、編集時はバックアップを取って慎重に進めることをお勧めいたします。
<?php
// 全角スペースで検索語句を区切る
if (isset($_GET['s'])) $_GET['s'] = mb_convert_kana($_GET['s'], 's', 'UTF-8');
// 検索対象にカスタム投稿タイプを含む
function include_cpt_search($query)
{
if (is_admin() || !$query->is_main_query()) {
return;
}
if ($query->is_search) {
$query->set('post_type', '-----「カスタム投稿タイプ名」を記述-----');
// $query->set( 'post_type', [ 'hoge', 'foo' ] ); // CPTが複数ある場合は配列で指定
}
}
add_filter('pre_get_posts', 'include_cpt_search');
// カスタムタクソノミー・カスタムフィールド関連
function custom_search($search, $wp_query)
{
global $wpdb;
if (!$wp_query->is_search)
return $search;
if (!isset($wp_query->query_vars))
return $search;
$search_words = explode(' ', isset($wp_query->query_vars['s']) ? $wp_query->query_vars['s'] : ''); // 検索データが存在する場合(三項演算子:条件? true: false)は、取得した検索データを半角スペース区切りで配列へ変換
if (count($search_words) > 0) { // 配列の中身が存在すれば下記の処理へ移行
$search = ''; // 関数の返却値(returnで指定)
foreach ($search_words as $word) {
if (!empty($word)) { // $wordが 空 || null の状態でない(falseの場合)なら下記の処理へ移行
$search_word = $wpdb->prepare("%%{$word}%%"); // プレースホルダーが使用できるprepare関数:'SQL 文字定数の中で%を使う場合、LIKE のワイルドカードも含めて %% のように二重の % を書いてエスケープ'
// .=(値を結合した形で変数に格納)
$search .= " AND (
{$wpdb->posts}.post_title LIKE '{$search_word}'
OR {$wpdb->posts}.post_content LIKE '{$search_word}'
OR {$wpdb->posts}.ID IN (
SELECT distinct r.object_id
FROM {$wpdb->term_relationships} AS r
INNER JOIN {$wpdb->term_taxonomy} AS tt ON r.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->terms} AS t ON tt.term_id = t.term_id
WHERE t.name LIKE '{$search_word}'
OR t.slug LIKE '{$search_word}'
OR tt.description LIKE '{$search_word}'
)
OR {$wpdb->posts}.ID IN (
SELECT distinct post_id
FROM {$wpdb->postmeta}
WHERE {$wpdb->postmeta}.meta_key IN ('-----「メタ:フィールド名」を記述-----','-----「メタ:フィールド名」を記述-----','-----「メタ:フィールド名」を記述-----') AND meta_value LIKE '{$search_word}'
)
) ";
}
}
}
return $search;
}
add_filter('posts_search', 'custom_search', 10, 2);
コメントアウトで明記していますが、
-
include_cpt_search
関数
検索対象にカスタム投稿タイプを含む処理 -
custom_search
関数
DBからカスタムタクソノミー・カスタム(メタ)フィールドを取得する処理
カスタム(メタ)フィールドが不要の場合は以下の部分を削除する。
OR {$wpdb->posts}.ID IN (
SELECT distinct post_id
FROM {$wpdb->postmeta}
WHERE {$wpdb->postmeta}.meta_key IN ('-----「メタ:フィールド名」を記述-----','-----「メタ:フィールド名」を記述-----','-----「メタ:フィールド名」を記述-----') AND meta_value LIKE '{$search_word}'
)
使用時には上記関数の所定箇所の変更が必要になります。
functions.php
内の sql 文は筆者の知識不足から古かったり、非推奨な記述になっている可能性もあります。
他にも spl 文のみならず、記述が間違っていたり、おかしかったりする部分がありますと、恐れ入りますがコメントなどでご指摘いただきますとありがたく存じます。
今回ご紹介したものは筆者のGitHub
にありますので、興味を持って下さった方は是非ご覧ください。
localstorage
を使った機能やスタイリングシートの用意など拡張版という形になっています。
さいごに
筆者がこれを自作した当時は(納期に迫られていることもあって)情報取集に苦労しました。あと検索の仕方が云々もあるかと思いますが……
今ではGPT
やcopilot
など生成AIがあり、より早くスマートな実装を教えてくれるでしょう。ただ筆者の実体験としては、自分で集めて、触って、改善して……というサイクルを通じたからこそ応用力が身に付いた気がします。とはいえ、当時GPT
があればバリバリ活用していたと思います。
この記事が昔の筆者のような方をお手伝いできる記事になっていたら嬉しく思います。
ここまで長々と拙文を読んでいただき、ありがとうございました。