Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

It is possible to search for posts with a specific term by appending the URL with:

?&term=abc

Is it possible to do the opposite and search excluding a specific term? Something like:

?&term=NOTabc
share|improve this question

1 Answer 1

up vote 7 down vote accepted

The basic explanation

  1. You have a template tag that is called is_search() to determin if you're on a search page or not.
  2. This then calls get_search_template() which basically is a wrapper function for get_query_template('search').
  3. When you look into the last function, then you'll see that it basically does locate_template(), which checks for file existence and then does a load_template().
  4. There your $wp_query->query_vars get checked and the $_template_file gets extracted and loaded.

A note before about the query var …

WordPress uses the query var s to save the searched term into its query. If you're running a custom query string, then you need to modify the get_search_query filter like the following:

/**
 * 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 );

Some solution(s)

We now have different possible solutions:

The easy solution

Runs in the template and better fits for excluding taxonomy terms.

A) Get all posts in the template loop, check every post in the loop for every (taxonomy) term 1) and then exclude/don't show it.

In you loop in your template search.php file:

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;
    } 
}

This is just an example of the loop.

The sophisticated solution(s)

Runs before running the actual main query and suits better for excluding terms in general.

B.1) Filter the term out of of the search template query.

In the following example I use the posts_clauses filter to show you that you can modify even more with just one filter (do a var_dump of the $pieces array for more insights). You could also use the posts_where filter, which runs before the clauses filter.

// 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' );
function alter_search_query( $pieces )
{
    global $wpdb;
    $term = $wpdb->esc_like( 'YOUR_TERM' );

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

    return $pieces;
}

B.2) Filter the term out of of the search template query _in a more performant & specific way.

In the following example I use the posts_search filter to show you how you can modify the where clause only for the search query. It's pretty much the same as the posts_where filter.

// 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' );
function alter_search_where( $search_term )
{
    global $wpdb;
    $term = $wpdb->esc_like( 'YOUR_TERM' );

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

    return $search_term;
}

Footnotes:

1) You haven't been clear if it's about a search or a taxonomy term.

share|improve this answer
2  
Great answer. Very informative. –  Chris_O Feb 3 '12 at 17:16
    
Thanks. I'm currently thinking about how to modify the tax_query using the pre_get_posts filter. That would sum all ways up. –  kaiser Feb 3 '12 at 17:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.