AD5 WordPress Lab

複数のタクソノミーやカスタムフィールドで検索するフォームを実装する

複数のタクソノミーやカスタムフィールドで検索するフォームを実装する

WordPressのデフォルトでは、カテゴリー(タクソノミー)別のアーカイブ、日付別のアーカイブなどが用意されていますが、商品や物件、店舗などの多くの情報を掲載するサイトでは、複数条件での検索を実装したい場合があります。

こうした複数条件での検索を、pre_get_postsフィルターへのフック等を用いて実装する方法のご紹介です。

検索条件は極力タクソノミーにする

例えば、productsという投稿タイプに対して、item、brand、targetという3つのタクソノミーがあったとします。

これを、3つのタクソノミーの組み合わせで検索できるようにしてみましょう。こんな風に。

まずはテンプレートに、以下のような検索フォームを用意します。
※わかりやすいように、HTMLで記述しています。

ポイントは、送信先(action)を、productsのアーカイブページである /products/ とすること。
(アーカイブテンプレートである archive-products.php には、標準ループが記述されていることが前提)

フォーム要素のinputやselectのnameを、タクソノミー名と合わせること。また、value値はタームのスラッグとすることです。

これだけで、サービス側は一切カスタマイズすることなく(!)、複数条件での検索が実装できます。

URLパラメータとクエリ変数(query_vars)

上記のようになるのは何故でしょうか?

上記の検索フォームで検索した結果のURLは、例えば以下のようになります。

http://example.com/products/?brand=vans&item%5B%5D=slipon&target%5B%5D=mens&target%5B%5D=unisex

この時、検索条件が格納されている、グローバル変数 $wp_query->query_vars (以下、クエリ変数)を見てみましょう。

必要な検索条件が全てセットされています。

WordPressでは、パーマリンク設定がデフォルトのとき、

デフォルト投稿のシングルページ
http://example.com/?p=123
カスタム投稿のアーカイブページ
http://example.com/?post_type=products
タクソノミーのアーカイブページ
http://example.com/?item=slipon

のように、GETパラメータを用いてURLが表現されます。

これらのいくつかのパラメータやタクソノミー名などは、パーマリンク設定を変更している場合であっても、WordPressがURLを解析する際に、自動的にクエリ変数に取り込まれます。

これらのパラメータが複数設定されていても同様で、複数条件での検索が実行されるのです。

タクソノミーで表現できない検索条件

例えば、文字列検索、範囲(From/To)検索、など、リストからの選択以外の検索を行う場合は、カスタムフィールドを用います。

例えば、投稿タイプproductsに、カスタムフィールド code と price を追加し、全社を部分一致の文字列検索、後者を数値の範囲検索とする場合、

code

今回は、入力要素のnameを、WordPressのデフォルトパラメータと重ならないようにしなければなりません。

検索処理は、pre_get_postsフィルターに、クエリ変数(query_vars)を書き換える処理をフックすることで実装します。

カスタムフィールドを検索条件に加える場合は、クエリ変数 meta_query を使います。

直感的にわかりやすいのは、以下のような実装でしょう。

code

これでも良いのですが、メインループ以外でproductsのデータを取得するときに、GETパラメータの影響を受けてしまう可能性があったり、逆にメインループ以外でこれらの絞込み条件を使い回せないなどの課題があります。

以下のようにした方が、よりWordPressの「お作法」に乗っ取った実装といえるでしょう。

code

まず、query_varsフィルタにフックした products_query_vars() で、WP_Queryクラスのquery_varsプロパティに、新たなキーを追加しています。
これにより、これらのキーに一致するURLパラメータも、URL解析の対象となり、クエリ変数(query_vars)に格納されます。

これらのオリジナルのクエリ変数は、検索に影響しないので、pre_get_posts フィルタにフックした処理で、検索に利用できるクエリ変数に変換します。

ソート順・表示件数の操作

ついでに、ソート順や表示件数をフォームで指定できるようにする方法も見ておきましょう。

まずはテンプレート側。

ソート順はクエリ変数 order と orderby、表示件数はクエリ変数 posts_per_page に渡せば良いのですが、やはりこれらはURLパラメータに付与しても、デフォルトではクエリ変数に渡ってくれません(プライベートクエリ変数:private_query_vars)。

そこで、カスタムフィールド検索と同様に、以下のように実装します。

code

おまけ:タクソノミー検索用のフォーム入力要素

タクソノミー検索を実装する際、該当するタームの一覧をselect要素のoptionやcheckboxにすることが多いですが、頻出かつ意外と手間なので、以下のように関数化しておくと便利です。

こんな風に使うと、冒頭に記載したようなフォーム要素が出力されます。

Plugin Outbound Posts – 記事リスト内に外部リンクを挿入

Outbound Posts – 記事リスト内に外部リンクを挿入

投稿のリストの中に、見た目は他の投稿のリンクと同じように、外部リンクを差し込みたい、なんてことはありませんか? こんな風に・・・ Outbound Posts は、このような記事風の外部リンクを簡単に投稿できるプラグインです。 このプラグインを有効化すると、各記事の投稿画面に、「外部リンク」という欄が現
Column WordPressが重い・遅いときは、まず「プラグインのスリム化」をしよう 〜調査篇〜

WordPressが重い・遅いときは、まず「プラグインのスリム化」をしよう 〜調査篇〜

WordPressが重い、遅い!? WordPressのサイトが重い、読み込みが遅いので高速化したい、という相談をよく受けます。 本シリーズでは、実際の高速化の実例を元に、事前調査から対応までの手順をご紹介します。 WordPressが遅い原因 経験上、WordPressが遅い原因の80%以上はプラグインの過剰使用です。 プラグイン
Column WordPressにXMLサイトマップを独自実装するカスタマイズ

WordPressにXMLサイトマップを独自実装するカスタマイズ

WordPressに限らず、SEO対策に不可欠なXMLサイトマップ。 カスタマイズせずとも「Google XML Sitemaps」などのプラグインで瞬殺なわけですが、 多くのXMLサイトマッププラグインは、柔軟に設定できるように作られている分、 「このサイトでは要らない機能」がたくさん含まれることになるので、多少なりともリソー
Plugin AD5 LOYALTY – WordPressで会員制サイト作成

AD5 LOYALTY – WordPressで会員制サイト作成

当サイトで使用しているプラグインです。 WordPressのサイトを簡単に会員制サイトにすることができます。 ショートコードで簡単に会員登録フォーム、ログインフォームが設置可能で、全ての投稿に対して、会員用コンテンツと非会員用コンテンツを設定することができます。 ショートコートで簡単に会員登録フォーム
Column WordPressテーマ・プラグイン開発時のセキュリティ対策

WordPressテーマ・プラグイン開発時のセキュリティ対策

WordPressのテーマやプラグインを開発、カスタマイズする際には、脆弱性を生まないよう、セキュリティ対策を十分に考慮する必要があります。 CSRF対策 管理画面内外を問わず、WordPressにリクエストを送信するフォームや、データを更新するAJAXを実装する場合には、CSRF対策を施しましょう。 リクエストを送信する
Plugin Mobile Sticky Footer – スマホ用固定フッター

Mobile Sticky Footer – スマホ用固定フッター

Mobile Sticky Footerは、スマートフォンサイトに簡単に固定フッターを設置できるWordPressプラグインです。 選べる3タイプのレイアウト 複数ボタンタイプは2ボタンから5ボタンまで設定可能。 お問合せフォームやSNSへのリンクのほか、電話ボタンの設置も可能です。 リアルタイムプレビューつきの直感的な設定画
Column WordPressにメールフォームを自力で実装する

WordPressにメールフォームを自力で実装する

WordPressにメールフォームを実装する優秀なプラグインは沢山ありますが、 ほとんどのプラグインは非開発者向けに導入しやすさを重視して作られているため、 例えば入力項目を動的にするなど、少し複雑なことをしようと思うと、 詰んでしまいます。 WordPressにはメール送信処理やデータの保存などを簡単に実装できる
Plugin WP LOYALTY Checkout add-on – クレジットカード決済

WP LOYALTY Checkout add-on – クレジットカード決済

当サイトで使用しているプラグインです。 AD5 LOYATYのアドオンとして、決済機能を提供します。 決済サービスとして、カード決済手数料が3.0%〜と安く、個人事業主でも利用可能なPAY.JPと連携できます。 (別途PAY.JPのアカウントが必要です。)
Column WordPressのテーマファイル構成を本気出して考えてみた

WordPressのテーマファイル構成を本気出して考えてみた

エンジニアの端くれとして、たかがWordPressテーマであっても、綺麗なモジュール設計がしたいわけです。 そこで、以前作ったサイトのテーマをモチーフに、テーマファイルを再設計してみました。 対象にしたサイトは、ユーザーが会員登録し、PDFコンテンツを投稿でき、ダウンロード結果を集計できるなど、そこそこ高機
Column WordPressサイトにパンくずリストをプラグインなしで実装する

WordPressサイトにパンくずリストをプラグインなしで実装する

意外と大変なパンくずリスト WordPressサイトに限らず、SEOの面でも重要視されるパンくずリスト(breadcramb nav)。 WordPressでガチで実装すると意外と面倒ですよね。 個別投稿ページだけでも、 A. 標準投稿 HOME > 親カテゴリ > 子カテゴリ > 投稿名 B. 固定ページ HOME > 親ページ >
 
ログイン
メールアドレス
パスワード
会員登録
お名前
メールアドレス
パスワード
購入手続き
カード番号
有効期限 (MM/YY)
/
セキュリティコード (CVC)