WordPress

【プラグインなし】カスタムフィールドの値で絞り込み検索:ORとANDの組み合わせのある複雑な条件

プラグインなしでWordPressのカスタムフィールドの値で絞り込む方法です。
複数のカスタムフィールドの値で、カスタムフィールド間はAND、カスタムフィールド内はORという複雑な条件の場合となります。

探してもズバリのものは見つからず苦労するので残します。

カスタムフィールドとは?

WordPressにはカテゴリーやタグ(タクソノミー/ターム)とは別にデータを持つ器としてカスタムフィールドが用意されています。投稿に紐づけることも、紐づけずに値を格納することも可能です。

カスタムフィールドに関して詳しくは以下の記事を参照ください。

カスタムフィールドをプラグインなしで追加する方法

カスタムフィールドの値を参照・取得する方法(プラグインなし)

カスタムフィールドに配列を格納、特定のキーのみ値を更新する方法(プラグインなし)

やりたいこと

この記事でご紹介するのは、次の例のように、絞り込む機能です。

地域はどこにするかを「東京都」「神奈川県」「埼玉県」「千葉県」から選び、
ランクはどのランクにするかを「ランクA」「ランクB」「ランクC」から選び、絞り込むことができるという機能です。

地域もランクも、複数選択が可能で、チェックボックスにします。

例えば「東京都」と「神奈川県」にチェックを入れれば検索条件は「東京都」OR「神奈川県」となります。

「ランクA」と「ランクB」にチェックを入れれば検索条件は「ランクA」OR「ランクB」となります。

地域とランクの間の検索条件はANDとなります。

つまり、「東京都」「神奈川県」「ランクA」「ランクB」の4つにチェックが入っている場合、検索条件は次の通りとなります。

(「東京都」OR「神奈川県」)AND(「ランクA」OR「ランクB」)

この検索条件、検索する際は直感的にこうであるはずと感じているはずなのですが、いざ作ろうと思うと案外ややこしい条件になっていると気づきます。

以下、実際にこの例に従ってご紹介していきます。

検索インタフェース部分

CSSによるデザインのことは考慮から除外しています。適宜お好みのデザインが当たるようにHTMLの構造は変えてください。

<form method="get" id="searchform" action="">
   <div>
      <input type="checkbox" id="tokyo" name="prefecture&#91;&#93;" value="東京都" <?php if(isset($_get&#91;'prefecture'&#93;) && (strpos($prefecture, '東京都') != false)) { echo 'checked'; } ?> />
      <label for="tokyo">東京都</label>
      <input type="checkbox" id="kanagawa" name="prefecture&#91;&#93;" value="神奈川県" <?php if(isset($_get&#91;'prefecture'&#93;) && (strpos($prefecture, '神奈川県') != false)) { echo 'checked'; } ?> />
      <label for="kanagawa">神奈川県</label>
      <input type="checkbox" id="saitama" name="prefecture&#91;&#93;" value="埼玉県" <?php if(isset($_get&#91;'prefecture'&#93;) && (strpos($prefecture, '埼玉県') != false)) { echo 'checked'; } ?> />
      <label for="saitama">埼玉県</label>
      <input type="checkbox" id="chiba" name="prefecture&#91;&#93;" value="千葉県" <?php if(isset($_get&#91;'prefecture'&#93;) && (strpos($prefecture, '千葉県') != false)) { echo 'checked'; } ?> />
      <label for="chiba">千葉県</label>
   </div>
   <div>
      <input type="checkbox" id="rank-a" name="rank&#91;&#93;" value="ランクA" <?php if(isset($_get&#91;'rank'&#93;) && (strpos($rank, 'ランクa') != false)) { echo 'checked'; } ?> />
      <label for="rank-a">ランクA</label>
      <input type="checkbox" id="rank-b" name="rank&#91;&#93;" value="ランクB" <?php if(isset($_get&#91;'rank'&#93;) && (strpos($rank, 'ランクb') != false)) { echo 'checked'; } ?> />
      <label for="rank-b">ランクB</label>
      <input type="checkbox" id="rank-c" name="rank&#91;&#93;" value="ランクC" <?php if(isset($_get&#91;'rank'&#93;) && (strpos($rank, 'ランクc') != false)) { echo 'checked'; } ?> />
      <label for="rank-c">ランクC</label>
   </div>
   <button type="submit" value="絞込み">絞込み</button>
</form>

name属性の値をprefecture[]のようにして、配列で値を入れていきます。チェック有無の状態維持のコードに関する解説は次の記事を参照ください。

カスタムフィールドに配列を格納、特定のキーのみ値を更新する方法(プラグインなし)

絞込み

次のコードで都道府県とランクの間はAND条件、都道府県間とランク間はOR条件の絞込みができます。

<?php
if (isset($_GET&#91;'prefecture'&#93;) && is_array($_GET&#91;'prefecture'&#93;)):
   $prefectire_arr = $_GET&#91;'gender'&#93;;
endif;
if (isset($_GET&#91;'rank'&#93;) && is_array($_GET&#91;'rank'&#93;)):
   $rank_arr = $_GET&#91;'rank'&#93;;
endif;
//meta_query用
if($prefecture_arr):
   foreach($prefecture_arr as $val):
      $mq_prefecture&#91;&#93; = array(
         'key'=>'prefecture',
         'value'=> $val,
         'compare'=>'LIKE'
         );
   endforeach;
   $mq_prefecture['relation'] = 'OR';
endif;
if($rank_arr):
   foreach($rank_arr as $val):
      $mq_rank[] = array(
         'key'=>'rank',
         'value'=> $val,
         'compare'=>'LIKE'
         );
   endforeach;
   $mq_rank['relation'] = 'OR';
endif;
$args = array(
   'posts_per_page' => 20,
   'paged' => $paged,
   'post_type' => 'shops', //カスタム投稿タイプ名
   'orderby' => 'date',
   'order' => 'DESC',
   'meta_query' => array(
      'relation' => 'AND',
      $mq_prefecture,
      $mq_rank
   ),
);
$the_queries = get_posts($args);
?>
<ul>
<?php foreach ($the_queries as $post) : setup_postdata($post); ?>
   <li>
       <?php the_title(); ?>
       <?php the_content(); ?>
   <li>
<?php endforeach; ?>
</ul>

ポイントとして、

<?php
   'meta_query' => array(
   'key'=>'rank', //カスタムフィールドのキー
   'value'=> '東京都', //絞り込む値
   'compare'=>'LIKE' //絞込み条件で、LIKEの場合は「含む」で絞り込み
),
?>

このように記載して絞り込めるmeta_queryをWordPressが用意しており、relationでAND条件、OR条件を設定が可能、かつネストさせることもできます。

上記のコードは、
$mq_prefecture['relation'] = 'OR';
で都道府県間をOR条件に設定しており、$mq_prefecture[]$mq_rank[]に代入した内容を踏まえると次の内容を実行していることになります。

<?php
'meta_query' => array(
   'relation' => 'AND', //都道府県とランクはAND
      array(
         'relation' => 'OR',//条件をネスト
         array(
            'key'=>'prefecture',
            'value'=> '東京都',
            'compare'=>'LIKE'
         ),
         array(
            'key'=>'prefecture',
            'value'=> '神奈川県',
            'compare'=>'LIKE'
         ),
         array(
            'key'=>'prefecture',
            'value'=> '埼玉県',
            'compare'=>'LIKE'
         ),
         array(
            'key'=>'prefecture',
            'value'=> '千葉県',
            'compare'=>'LIKE'
         ),
      ),
      array(
         'relation' => 'OR',//条件をネスト
         array(
            'key'=>'rank',
            'value'=> 'ランクA',
            'compare'=>'LIKE'
         ),
         array(
            'key'=>'rank',
            'value'=> 'ランクB',
            'compare'=>'LIKE'
         ),
      ),
);
?>

まとめ

以上で、カスタムフィールドでANDとORが両方ある複雑な条件での絞込み検索が実現可能です。

著者のイメージ画像

BringFlower
稲田 高洋(Takahiro Inada)

2003年から大手総合電機メーカーでUXデザインプロセスの研究、実践。UXデザイン専門家の育成プログラム開発。SEOにおいても重要なW3Cが定めるWeb標準仕様策定にウェブアクセシビリティの専門家として関わる。2010~2018年に人間中心設計専門家を保有、数年間ウェブアクセシビリティ基盤委員も務める。その後、不動産会社向けにSaaSを提供する企業の事業開発部で複数サービスを企画、ローンチ。CMSを提供し1000以上のサイトを分析。顧客サポート、サイト運営にも関わる。
2022年3月にBringFlowerを開業し、SEOコンサル、デザイン、ウェブ制作を一手に受ける。グッドデザイン賞4件、ドイツユニバーサルデザイン賞2件、米国IDEA賞1件の受賞歴あり。
プロフィール詳細