web-dev-qa-db-ja.com

検索から特定の用語を除外する

次のURLを追加することで、特定の語句を含む投稿を検索できます。

?&term=abc

特定の用語を除外して反対の検索をすることは可能ですか?何かのようなもの:

?&term=NOTabc
6
Rob

基本的な説明

  1. 検索ページにいるかどうかを判断するためのis_search()というテンプレートタグがあります。
  2. その後、これはget_search_template()を呼び出します。これは基本的にget_query_template('search')のラッパー関数です。
  3. 最後の関数を見ると、それが基本的にlocate_template()を実行し、それがファイルの存在をチェックしてからload_template()を実行していることがわかります。
  4. $wp_query->query_varsがチェックされ、$_template_fileが抽出されてロードされます。

クエリ変数についての前のメモ…

WordPressは検索語をクエリに保存するためにクエリvar sを使います。カスタムクエリ文字列を実行している場合は、次のようにget_search_queryフィルタを変更する必要があります。

/**
 * Modify search query var
 * Doesn't need to be wrapped into esc_attr(), as it's already done by core
 * 
 * @param string $s | The query var to save the search in
 * @return string $s
 */
function change_search_query_var( $s )
{
    $s = 'your_custom_query_var';

    return $s;
}
add_filter( 'get_search_query', 'change_search_query_var', 20, 1 );

いくつかの解決策

私たちは今、さまざまな可能な解決策を持っています。

簡単な解決策

テンプレート内で実行され、分類用語を除外するのに適しています。

A) テンプレートループ内のすべての投稿を取得し、すべての(分類法)用語についてループ内のすべての投稿をチェックする 1) それから除外したり、表示しないでください。

テンプレートsearch.phpファイルをループします。

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();

        global $post;
        // Skip if the post has the term attached
        if ( is_object_in_taxonomy( 
            $post->ID,
            'YOUR_TAXONOMY',
            array( 'TERM A', 'TERM B', '...' ) 
        )
        continue;
    } 
}

これはループの一例です。

洗練された解決策

実際のメインクエリを実行する前に実行され、一般的に用語を除外するのに適しています。

B.1) 検索テンプレートクエリから用語を除外します。

次の例では、posts_clausesフィルタを使用して、1つのフィルタでさらに変更できることを示します(詳細についてはvar_dump配列の$piecesを実行します)。句フィルターの前に実行されるposts_whereフィルターを使用することもできます。

// In your functions.php file
/**
 * Modify the search query where clause
 * Like escapes the term for security reasons
 * 
 * @param array $pieces | The array of post clauses: Where, Group by, etc.
 * @return array $pieces
 */
add_filter( 'posts_clauses', 'alter_search_query', 10, 2 );
function alter_search_query( $pieces, $query )
{
    // Target all search queries in the front-end:
    if( is_admin() || ! $query->is_search() ) return $pieces;

    global $wpdb;
    $term = $wpdb->esc_like( 'YOUR_TERM' );

    $pieces['where'] .= $wpdb->prepare( 
        " AND   {$wpdb->posts}.post_title NOT LIKE '%s'",
        "%{$term}%" 
    );

    return $pieces;
}

B.2) 検索テンプレートのクエリから検索語句を除外する。

次の例では、検索クエリに対してのみwhere句を変更する方法を示すためにposts_searchフィルタを使用します。 posts_whereフィルタとほとんど同じです。

// In your functions.php file
/**
 * Modify the search query where clause
 * Like escapes the term for security reasons
 * 
 * @param array $pieces | The array of post clauses: Where, Group by, etc.
 * @return array $pieces
 */
add_filter( 'posts_search', 'alter_search_where', 10, 2 );
function alter_search_where( $search_term, $query )
{
    // Target all search queries in the front-end:
    if( is_admin() || ! $query->is_search() ) return $search_term;

    global $wpdb;
    $term = $wpdb->esc_like( 'YOUR_TERM' );

    $search_term .= $wpdb->prepare( 
        " AND   {$wpdb->posts}.post_title NOT LIKE '%s'",
        "%{$term}%" 
    );

    return $search_term;
}

脚注:

1) search または taxonomy という用語については明確ではありません。

11
kaiser

@kaiserが上に投稿した非常に詳細で徹底的な答え。最初のメソッドを使いたかったのですが、Current wp 4.7で使われていた最初のメソッドの関数がうまくいかないようです。

現在の投稿に割り当てられている分類法の特定の用語をチェックするには、has_termの代わりにis_object_in_taxonomyと呼ばれる他のWordpressの関数を使用する必要があります。

これはあなたのsearch.phpあなたが検索結果のために使用しているどんなカスタムページテンプレートでもhas_term関数を使うことによって私のために働いた最終的なコードです。

if ( have_posts() ) : while ( have_posts() ) : the_post();

//Skip the post if property taxonomy rl_status is sold or rented: 
    if(has_term(array( 'sold', 'rented' ), 'rl_status', get_the_ID() ){

        continue;
            }
0
Mohsin