Search code examples
phpwordpresssearchcustom-taxonomyhook-wordpress

Exclude multiple custom taxonomies terms from Wordpress search


I am excluding from Wordpress search results any posts or custom posts with custom taxonomies set to specific terms. I want to be able to add more taxonomies and terms simply (like in an array) without having the duplicate the function, and ensure I'm doing it efficiently.

Can anyone suggest a cleaner function that accommodates this?

/* Exclude from WordPress Search using custom taxonomy */
add_action( 'pre_get_posts', function ( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    // Exclude Terms by ID from Search and Archive Listings
    if ( is_search() || is_tax( 'marque' ) ) {    
        $tax_query = array([
            'taxonomy' => 'site_search',
            'field' => 'term_id',
            'terms' => [ exclude_page ],
            'operator' => 'NOT IN',
        ]);

        $query->set( 'tax_query', $tax_query );
    }
}, 11, 1 );


/* Exclude from WordPress Search using custom taxonomy */
add_action( 'pre_get_posts', function ( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    // Exclude Terms by ID from Search and Archive Listings
    if ( is_search() || is_tax( 'marque' ) ) {    
        $tax_query = array([
            'taxonomy' => 'job_status',
            'field' => 'term_id',
            'terms' => [ closed ],
            'operator' => 'NOT IN',
        ]);

        $query->set( 'tax_query', $tax_query );
    }
}, 11, 1 );

Solution

  • You could try first to define all your data in an array first as taxonomies / terms pairs (I have embedded the array in an external function, but it can be added directly in the hooked function). This way you can add or remove data easily.

    Then we use a foreach loop to read and set the data in the tax query. So your code will be something like:

    // HERE set in the array your taxonomies / terms pairs
    function get_custom_search_data(){
        return [
            'site_search' => [ 'exclude_page' ],
            'job_status'  => [ 'closed' ],
        ];
    }
    
    /* Exclude from WordPress Search using custom taxonomy */
    add_action( 'pre_get_posts', 'multiple_taxonomy_search', 33, 1 );
    function multiple_taxonomy_search( $query ) {
        if ( is_admin() || ! $query->is_main_query() ) {
            return;
        }
    
        // Exclude Terms by ID from Search and Archive Listings
        if ( is_search() || is_tax( 'marque' ) ) {
            // Set the "relation" argument if the array has more than 1 custom taxonomy
            if( sizeof( get_custom_search_data() ) > 1 ){
                $tax_query['relation'] = 'AND'; // or 'OR'
            }
    
            // Loop through taxonomies / terms pairs and add the data in the tax query
            foreach( get_custom_search_data() as $taxonomy => $terms ){
                $tax_query[] = [
                    'taxonomy' => $taxonomy,
                    'field' => 'slug', // <== Terms slug seems to be used
                    'terms' => $terms,
                    'operator' => 'NOT IN',
                ];
            }
    
            // Set the defined tax query
            $query->set( 'tax_query', $tax_query );
        }
    }
    

    Code goes in function.php file of your active child theme (or active theme). Untested, it should work.