I'm trying to add a tax_query for the query of a custom post type single page with this code.

function wcua_pre_get_posts ($query) {
    // Also removed this condition
    if( is_admin() || ! $query->is_main_query() ) {

    $contest = get_query_var('contest');
    if( ! empty($contest) ) {
        $query->set('tax_query', [
                'taxonomy' => 'contest',
                'field'    => 'slug',
                'terms'    => [$contest], // Also sent it as a string and removed the operator
                'operator' => 'IN'
add_action('pre_get_posts', 'wcua_pre_get_posts');

But it does not work. The result is not filtered. To test that it reaches that condition, I added a breakpoint and it does but the result is not filtered. Besides that I also added another thing $query->set('post__not_in', [1]) just to test and it does appear in the query, and the result does not change but I know the query changes.

I searched on the whole site and there are a few hooks for pre_get_posts but nont alter the tax_query. Also change the priority to 10k.

This is the register_taxonomy code for the custom post type

register_taxonomy('contest', 'entry', [
    'hierarchical'          => true,
    'labels'                => [
        'name'                       => _x( 'Contests', 'taxonomy general name' ),
        'singular_name'              => _x( 'Contest', 'taxonomy singular name' )
    'show_ui'               => true,
    'show_admin_column'     => true,
    'query_var'             => true,
    'publicly_queryable'    => true,
    'rewrite'               => array( 'slug' => 'contest' )

// Doing a rewrite rule for the CPT 
add_rewrite_rule('^([a-z-]+)/([0-9]+)/([a-z]+)/?', 'index.php?post_type=entry&contest=$matches[1]&contest_year=$matches[2]&name=$matches[3]', 'top');
add_rewrite_tag('%contest_year%', '([0-9]+)va');

// Query vars are set

Printed the $wp_query to see what it has and I see the tax_query in the query_vars array with what I added, but the tax_query property is NULL.

add_action('the_post', function() {
    global $wp_query; 
    echo '<pre>';
    echo '</pre>';

What could I be doing wrong? Did I forget something? Queries for CPT individual pages can't be changed?

  • "custom post type single page" and "CPT individual pages" - why would you add a taxonomy query to the main query on single post pages? What were you really trying to do?
    – Sally CJ
    Commented Aug 19, 2022 at 1:59
  • If i go to /contest-that-exists/2022/name-of-artist and /contest-that-does-not-exist/2022/name-of-artist, both work and throws the same entry (a picture of their art). But the artist could submit different art different years. I could filter the year, and that works but the first part of the url would still work even if the contest of the name does not exist. I guess another approach could be just to throw a 404 if the first part is not found in some other hook. Commented Aug 19, 2022 at 2:27
  • What you said makes sense and I thought about it but wasn't sure because I watched this video where they added a meta_query and thought that a tax_query could be applied as well. youtu.be/ECFVrBoQYRw?t=2142 Commented Aug 19, 2022 at 2:33
  • So you are basically trying to disable the latter URL (/contest-that-does-not-exist/...), right? And unfortunately, that happens because as long as the post name/slug is good, then WordPress will load the correct post page. The good side, though, is that if one didn't remember the full URL, then only by knowing the post slug, would help the user land on the correct page. And yes, you can disable it by issuing a 404 error, and in fact, there's an example here for taxonomy terms.
    – Sally CJ
    Commented Aug 19, 2022 at 2:47
  • Thanks for the help! Ended up doing something weird: on save_post I save the uri part (/contest/year/artist-name) as entry_path on the postmeta table and then on pre_get_posts I put the meta_query to filter by entry_path (building the uri). It also throws 404. I don't like this solution but until I read more the wp core code, it is enough. Commented Aug 19, 2022 at 4:51


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.