Exclude specific terms from all queries using posts_where or something similar

My SQL knowledge is quite bad, I should admit, so I’m going to use a non SQL way to achieve this.

Here is my idea:

Use pre_get_posts to alter the query variables before the main query is executed. As all of the query variable has been set by the time pre_get_posts run, you can simply change them as needed, and also, the conditional tags are available, so you can do what you need conditionally.

For, example, you said you need to exclude a certain term, so you can use a tax_query to exclude the term from the main query, and use is_tax to allow that term on the specific taxonomy page

Something like this might work. Please note: This is untested

function wpse_exclude_term( $query ) {
    if ( !is_admin() && $query->is_main_query() && !is_tax( 'TAXONOMY_NAME', 'TERM_NAME/SLUG/ID' ) ) {
        $tax_query = array(
            array(
                'taxonomy' => 'TAXONOMY_NAME',
                'field'    => 'slug',
                'terms'    => 'TERM_SLUG',
                'operator' => 'NOT IN'
            ),
        );
        $query->set( 'tax_query', $tax_query );
    }
}
add_action( 'pre_get_posts', 'wpse_exclude_term' );

RUNDOWN ON SOME OF THE IMPORTANT CODE

  • !is_tax( 'TAXONOMY_NAME', 'TERM_NAME/SLUG/ID' ) Conditional check which check if you are not on the specific taxonomy page. Note the NOT operator (!)

  • !is_admin() && $query->is_main_query() Basically just make sure that changes are only made in the main query and on the front end

  • 'operator' => 'NOT IN' This excludes the specific term specified in the tax_query