サポート » 使い方全般 » 複数カスタムタクソノミーでのOR検索の方法

  • お世話になります。

    複数のカスタムタクソノミーからのOR検索ができるフォームを作成したいと思っております。

    作りたい検索フォーム

    タクソノミー1と
    タクソノミー2のタームをチェックボックスで表示し、
    チェックしたタームに該当する記事を検索結果に表示する

    例)
    タクソノミー1のターム1、またはターム2、または
    タクソノミー2のターム1、またはターム2に該当する記事をすべて表示する(OR検索)

    自分で色々調べてタクソノミー1のみの場合であればOR検索ができるようになったのですが、
    タクソノミー1とタクソノミー2の複数のカスタムタクソノミーに該当する記事を検索できる検索フォームはどのように記述したらいいのかわからず困っております。

    検索結果ページ

    <?php
    $s = $_GET[‘s’];
    $post_tag = $_GET[‘post_tag’];

    //tax_query用
    if($post_tag){
    $taxquerysp[] = array(
    ‘taxonomy’=>’workstyle’,
    ‘terms’=> $post_tag,
    ‘include_children’=>false,
    ‘field’=>’slug’,
    ‘operator’=>’in’
    );
    }
    ?>

    <div>検索条件</div>
    <?php if($s){ ?>検索キーワード:<?php echo $s; ?><?php } ?>
    <?php
    if (is_array($post_tag)) { ?>タグ(カスタムタクソノミー):<?php
    foreach($post_tag as $val){
    if ($val === end($post_tag)) {
    echo get_term_by(‘slug’,$val,”post_tag”)->name;
    }else{
    echo get_term_by(‘slug’,$val,”post_tag”)->name.”, “;
    }
    }
    }
    ?>

    <div>検索結果</div>

    <?php
    query_posts( array(
    ‘tax_query’ => $taxquerysp,
    ‘s’ => $s,
    )
    );
    ?>
    <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

    <div><?php the_title(); ?></div>
    <div><?php the_content(); ?></div>

    <?php endwhile; else : ?>

    <div>該当なし</div>

    <?php endif;
    wp_reset_query(); ?>

    検索フォーム

    <form method=”get” id=”searchform” action=”<?php bloginfo(‘url’); ?>”>

    <input type=”hidden” name=”s” id=”s” placeholder=”検索” />

    <div>カスタムタクソノミー1</div>
    <?php
    $taxonomy_name = ‘workstyle’;
    $taxonomys = get_terms($taxonomy_name);
    if(!is_wp_error($taxonomys) && count($taxonomys)):
    foreach($taxonomys as $taxonomy):
    $tax_posts = get_posts(array(‘post_type’ => get_post_type(), ‘taxonomy’ => $taxonomy_name, ‘term’ => $taxonomy->slug ) );
    if($tax_posts):
    ?>
    <label><input type=”checkbox” name=”post_tag[]” value=”<?php echo $taxonomy->slug; ?>”><?php echo $taxonomy->name; ?></label>
    <?php
    endif;
    endforeach;
    endif;
    ?>

    <input type=”submit” value=”検索” />
    </form>

    ここから、さらにどのように記述すると
    カスタムタクソノミーの複数検索ができるようになるでしょうか。
    お手数をおかけしますが、みなさまのお知恵をお貸しください。
    どうぞよろしくお願いします。

11件の返信を表示中 - 1 - 11件目 (全11件中)
  • tax_queryのrelation引数が役立つと思います。WP_Queryの説明ページの Nested Taxonomy Handling セクションが参考になります。
    http://wpdocs.osdn.jp/関数リファレンス/WP_Query

    トピック投稿者 conte9999

    (@conte9999)

    ご回答ありがとうございます!
    参考にして作りなおしてみたいと思います。

    その上で申し訳ありません、
    もう一つ、どうしても気になっているのですが
    わからないことがあるので教えてもらえませんでしょうか。

    $args = array(
    ‘tax_query’ => array(
    ‘relation’ => ‘AND’,
    array(
    ‘taxonomy’ => ‘movie_janner’,
    ‘field’ => ‘slug’,
    ‘terms’ => array( ‘action’, ‘commedy’ )
    ),
    array(
    ‘taxonomy’ => ‘actor’,
    ‘field’ => ‘id’,
    ‘terms’ => array( 103, 115, 206 ),
    ‘operator’ => ‘NOT IN’
    )
    )
    );
    $query = new WP_Query( $args );

    ‘terms’ => array( ‘action’, ‘commedy’ )

    の部分なのですが、
    ここでターム名を任意に指定してまったら
    カスタムタクソノミー全体(たとえば上記のコードで言えばスラッグ名”actor”)が検索範囲に入らなくなってしまう気がするのですが、

    カスタムタクソノミー全体を検索範囲にするには
    この部分はどのように記述すると良いのでしょうか。

    無知ゆえの質問をしているのだと自覚しておりますし
    まとも外れているのかもしれませんから
    本当に申し訳ないのですが、どうぞよろしくお願いします。

    状況と、やりたいことを整理しましょう。
    まず状況。タクソノミーAのタームXYZ、タクソノミーBのXYZ、タクソノミーCのXYZというように、同じXYZだけれどタクソノミーがたくさんある(後から増えたり減ったり)。ここまではよいでしょうか。

    次にやりたいこと。タクソノミーが増減するたびにコードを書き直したくない。どうすればよいか。 …こういうことでしょうか?

    トピック投稿者 conte9999

    (@conte9999)

    ご指導ありがとうございます。知識どころか私のコミュニケーション不足でわかりにくくなっており申し訳ありません。

    >タクソノミーAのタームXYZ、タクソノミーBのXYZ、タクソノミーCのXYZというように、同じXYZだけれどタクソノミーがたくさんある(後から増えたり減ったり)。ここまではよいでしょうか。

    はい。その通りです。

    >次にやりたいこと。タクソノミーが増減するたびにコードを書き直したくない。どうすればよいか。 …こういうことでしょうか?

    はい。これもその通りです。タクソノミーは随時、ワードプレスの管理画面から追加される可能性があり、増減する度にコードを書き直すことは現実的ではないので毎回コードを書き直さなくていい方法を探しております。

    お忙しいところ本当に恐れ入りますがぜひご教授ください。
    どうぞよろしくお願いします。

    tax_query を使うには taxonomy を省略できない筈(検証してませんが)なので、難しいんじゃないでしょうか。wpdbクラスのメソッドを使ってWordPressデータベースを検索すれば何とかなるかもですが、私には難しいです。

    conte9999さん、実現方法をもう少し考えてみました(検証していませんが)。

    検索フォームで「タクソノミー1のターム1」がチェックされたら、検索結果ページへ渡すクエリ文字列に「タクソノミー1のIDとターム1のID」をペアで含めます。複数チェックされていたら、その分だけ複数のペアを含めます。(チェックボックスの value にタクソノミーIDとタームIDのペアを入れておく。)

    例えば /wordpress/kensaku.php?myterms=tax1+term1+tax2+term2+…

    ただし myterms というカスタムクエリ変数をあらかじめWordPressに登録しておきます。これについては、関数リファレンス/get query var の「カスタムクエリ変数」セクションを見てください。

    検索結果ページは、クエリ文字列から「タクソノミーIDとタームID」の複数のペアを取り出して、foreachループで1ペアずつ処理して tax_query 引数を組み立てます(OR で繋ぐ)。get_query_var 関数で取り出せます。なお、同じタクソノミーIDが複数回出てくる場合があるので、それらをまとめる処理も行なって OR で繋ぐ個数を減らすとよいでしょう。

    少し訂正です。

    例えば /wordpress/kensaku.php?myterms=tax1+term1+tax2+term2+…

    これだとtax1とterm1のペアが崩れるかもしれないので、下記に訂正します。

    myterms=tax1+term1,tax2+term2,tax3+term3…

    トピック投稿者 conte9999

    (@conte9999)

    gblsm様、お忙しいところほんとうに丁寧にご指導を下さりありがとうございます。

    いただいた情報を参考に作成してみたいと思います。

    重ねてではありますがほんとうにありがとうございました。
    またお世話になることがあるかもしれませんが、
    今後とも何卒よろしくお願いいたします。

    モデレーター Takuro Hishikawa

    (@hissy)

    ご質問内容とは関係ありませんが、検索結果ページのコードにXSS脆弱性がありますので、修正した方が良いでしょう。

    トピック投稿者 conte9999

    (@conte9999)

    Takuro Hishikawa様、ご指導ありがとうございます。

    下記の検索結果ページのコードにXSS脆弱性があるとのこと
    そのような危険があることすら全くわかっていなかったので
    ご指摘いただけたこと本当に感謝しております。

    その上で、本当に厚かましいお願いで申し訳ないのですが
    アドバイスいただけないでしょうか。

    たとえば、
    ttp://blog.katty.in/95
    この記事に書いてある

    1. <>“&は文字参照にする

    の対策を下記のコードの何処かに挿入すると良いのかと思うのですが、
    どこに挿入したらいいのかどうしてもわかりませんでした。

    どのように対策すればいいのかご指導いただけないでしょうか。
    まったく素人の状態でこのような質問をしていること
    本当にお恥ずかしいのですが、少しずつでも学んでいきたいと思っています。

    お手数をおかけしますが、どうぞよろしくお願いいたします。

    <?php
    $s = $_GET[‘s’];
    $post_tag = $_GET[‘post_tag’];

    //tax_query用
    if($post_tag){
    $taxquerysp[] = array(
    ‘taxonomy’=>’workstyle’,
    ‘terms’=> $post_tag,
    ‘include_children’=>false,
    ‘field’=>’slug’,
    ‘operator’=>’in’
    );
    }
    ?>

    <div>検索条件</div>
    <?php if($s){ ?>検索キーワード:<?php echo $s; ?><?php } ?>
    <?php
    if (is_array($post_tag)) { ?>タグ(カスタムタクソノミー):<?php
    foreach($post_tag as $val){
    if ($val === end($post_tag)) {
    echo get_term_by(‘slug’,$val,”post_tag”)->name;
    }else{
    echo get_term_by(‘slug’,$val,”post_tag”)->name.”, “;
    }
    }
    }
    ?>

    <div>検索結果</div>

    <?php
    query_posts( array(
    ‘tax_query’ => $taxquerysp,
    ‘s’ => $s,
    )
    );
    ?>
    <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

    <div><?php the_title(); ?></div>
    <div><?php the_content(); ?></div>

    <?php endwhile; else : ?>

    <div>該当なし</div>

    <?php endif;
    wp_reset_query(); ?>

    conte9999さん、XSS脆弱性の一つのパターンは、何かを表示するときに「入力されたものをそのまま表示してしまう」です(他にもあります)。このパターンが、検索結果ページのどのコードに該当するか、ご自身で挙げてみてください。

    ところで対策の方はWordPressの関数 esc_attr を使うとよいですよ。esc_attrの説明ページに例が載っています。

11件の返信を表示中 - 1 - 11件目 (全11件中)
  • トピック「複数カスタムタクソノミーでのOR検索の方法」には新たに返信することはできません。