Query set using tax_query with relation ‘OR’ modifies category object?

(Update: Please see the edits far below.)

The code:

function itsme_better_editions( $query ) {
    if ( $query->is_category() && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post' ) );
        $query->set( 'tax_query',
            array(
                'relation' => 'OR',
                array(
                    'taxonomy' => 'category',
                    'field' => 'slug',
                    'terms' => 'intl',
                    'operator' => 'IN'
                )
            )
        );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'itsme_better_editions' );

I am using this function to display posts assigned to ‘International (intl)’ category under all categories i.e. in all category archives.

(In my case categories represent Editions as common with a news site, for example.)

The problem is, with the function in place, it appears as though the term object of all archives gets set to ‘International (intl)’, be it a category archive, tag archive, custom taxonomy archive, etc.

So, for example, if I visit the ‘UK (uk)’ category archive, the <?php single_cat_title(); ?> displays ‘International’ instead of ‘UK’. (NOTE: single_cat_title() is just an example, and only one of the problems caused by the change in term object.)

Why is this happening? (Despite me setting 'relation' => 'OR'.) What should I do to fix this?

PS: Surprisingly this used to work (very positive), and I don’t know in which version of WordPress this broke.

EDIT: The problem, I just realized, appears to be that $tax_query = $query->get( 'tax_query' ); is empty or not an array. I am not really sure why this is happening, and what’s wrong with my code.

Related Question: When/why does '$query->get( 'tax_query' );' return empty?

1 Answer
1

The issue is you are overriding the entire tax_query. When you go to the UK category archive, tax query is set to have the same thing you have for International, but you are nuking the current query. Here is the solution:

...
$tax_query = $query->get('tax_query');
$tax_query['relation'] = 'OR';
// puts the item at the beginning of the array instead of the end.
array_unshift( $tax_query, array(
        'taxonomy' => 'category',
        'field' => 'slug',
        'terms' => 'intl',
        'operator' => 'IN'
    );
$query->set( 'tax_query', $tax_query );
...

Leave a Comment