この記事のコードはちゃんと動いてませんでした。近日中に修正いたします。
2014.04.03追記:
修正版書きました
以前カスタムタクソノミーを好みの条件で検索する方法として、カスタムタクソノミーを使った複雑な条件検索というエントリーを書きました。
当時は$_GETで得た値をtax_queryに突っ込むという方法を取っていましたが、$_GETを直接取得するというのは明らかにダサいですしWordPressらしくもありません。
そこで検索に用いるタクソノミー名をクエリオブジェクトより取得する方法を改めて考えてみました。ついでに通常のループ+pre_get_postsで取得できるようにしてみました。
ADs
カスタムタクソノミーはregister_taxonomy関数で定義しますが、その際「query_var」というオプションをtrueにセットします。
そうすることで定義したカスタムタクソノミー名をクエリとして扱うことが出来ます。
1 2 3 4 5 6 7 |
register_taxonomy( 'label' => '名前', 'labels' => array( ...ダッシュボードで表示される名前など ), 'query_var' => true //これが必要 ) |
検索フォーム部分はnameにカスタムタクソノミーの名称、valueにそれぞれのタクソノミーの内容の名前(分かりにくい言い回しですが・・・)を入力します。
ループ部分はpre_get_postsフィルタを使う場合、while部分以外の記述は必要ありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<form action="./" method="get"> <dl> <dt>材質</dt> <dd> <input type="checkbox" name="material[]" value="金属" />金属 <input type="checkbox" name="material[]" value="木" />木 <input type="checkbox" name="material[]" value="布" />布 </dd> </dl> <dl> <dt>産地</dt> <dd> <input type="checkbox" name="born[]" value="海外" />海外 <input type="checkbox" name="born[]" value="国内" />国内 </dd> </dl> <dl> <dt>フリーワード</dt> <dd><input type="text" name="s" /></dd> </dl> <input type="submit" value="検索する" /> </form> <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <div class="article"> <h2><?php the_title(); ?></h2> <div> <?php the_content(); ?> </div> <div class="tax"> 産地:<?php the_terms( $post->ID, 'born'); ?><br /> 素材:<?php the_terms( $post->ID, 'material'); ?> </div> </div> <?php endwhile; else: ?> <p>投稿はありません。</p> <?php endif; ?> |
$query->queryをvar_dumpなどで見てみると分かりやすいのですが、単にフォームからのGET値が入っているわけではなく、GETで送られてかつカスタムタクソノミーとして定義している値のみがqueryとして保持されています。
この$query->queryを使ってtax_queryを生成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php function taxonomy_search($query) { if ( is_admin() || ! $query->is_main_query() ){ return; } //$queryの中身を見てみると分かりやすいかもしれません。 //var_dump($query); //クエリがある場合のみの条件分岐。is_search()とかis_archive()のほうが望ましい場合もあると思う if ( count($query->query) ) { //設定済みタクソノミーの取得 $alltax = get_taxonomies(array( '_builtin' => false //WPがデフォルトで持っているタクソノミー(categoryとかpost_tagとか)を除く )); //tax_queryで使う配列を生成 $arr = array(); //最終的にtax_queryに突っ込む配列 foreach($query->query as $key=>$val){ if(in_array($key,$alltax)){ $arr +=array( 'taxonomy' => $key, 'field' => 'slug', 'terms' => array_merge($val),//$valが配列なので。。。 'operator' => 'IN' ); } } //最低限の条件 $query->set('post_status','publish'); $query->set('post_type','post'); //tax_queryをセット $query->set('tax_query',array( 'relation' => 'AND', //OR検索をしたい場合は'OR'で $arr )); return $query; } } add_action( 'pre_get_posts', 'taxonomy_search' ); ?> |
ADs
こんにちは。
以前投稿していた旧Verでは、条件検索ができたのですが、
このソースをそのまま使用し、試した所404エラー等が連発してしまいました。
のあ 様
コメントありがとうございます。
このソースそのままで実際に動かしてみたところ私の環境では動いておりますので(https://wood-roots.com/test/ 念のためWP3.8.1にアップデートしました)、動作しないのでしたらエラーのもう少し詳しい状況をお伝えいただけますと解決も早いかと思います。
たとえば、
・WordPressはどのバージョンを使っているのか
・実際に表示されるエラーメッセージはどのようなものか(ini_set( ‘display_errors’, 1 );を記述していないとメッセージは表示されません)
・どのタイミングでエラーが表示されるのか(ページにアクセスしたとき?検索を実行した時?)
などの情報が分かるとどこで問題が発生しているのか原因究明が捗ります。
また、可能であれば設置して動作していないサイトのURLをお伝えいただければなおいいかと思います。
ご丁寧にご返信ありがとうございます。
Wordperssのバージョンは3.8.1を使用しております。
また、エラーではないのですが、 検索する ボタンを押したあとでも該当する記事が表示されない状態となっております。
ID:***********
Pass:**********
のあ 様
コメントありがとうございます。
誠に申し訳ありません。いただいたパスワードでテーマを直接変更して見ていたら記述をミスってしまい、更新作業ができなくなってしまいました。。。。
お伝えいただいたサイトもエラーで表示されない状態になっているかと思います。
修正していたのはfunctions.phpなので、おそれいりますが再度アップロードしていただけますでしょうか。
本当にすいません。。。。
お手数をおかけいたします^^;
先ほど元のファイルに戻しましたので、よろしくお願いいたします。
のあ様
テスト用のサーバのfunctions.phpを改造させていただき、おそらく思い通りの動作ができるようになったのではないかと思います。
※ID、Passはテストサーバとはいえ公開しておくのはまずいと思うので編集させていただきました。
当記事に書いている内容でもエラー出力させてみるとエラーまみれだったりよく見たら動作がおかしかったりしたので、記事も近日修正いたします。。。
修正箇所はfunctions.phpのみで、コメントを入れていますので参考にしてみてください。
Morimoto様お忙しい所ありがとうございました!
大変勉強になります。
今後ともよろしくお願いいたします。