CPT archive 404ing when using a custom taxonomy name as a variable

So, I’m using a custom post type archive and generating a JavaScript-based filtering interface for sorting through results.

Here’s an example: http://www.inverity.org/sermons/

Read More

Now, what I’d like to do is pass in variables to my script to allow for filtering based on URL parameters.

This works: http://www.inverity.org/sermons/?presenters=4

The problem is, this doesn’t: http://www.inverity.org/sermons/?speakers=4

“speakers” is the name of the custom taxonomy I’m using and is the value that I want to filter by.

Any ideas why this is happening? Is there anything I can do to get around it and prevent the 404ing?

Related posts

Leave a Reply

2 comments

  1. I had the same problem on my large project that I currently work on. It’s case when you have collision between taxonomy and post-type slugs. Problem is that you can filter by taxonomy with adding ?taxonomy_name=term_slug and also you can see the custom post by adding ?post_type=custom_post_slug. So, that’s the same syntax, and WP doesn’t know do you want “term archive” or “single custom post”.

    The only, and the right way (in my opinion) to solve this is to change either taxonomy-slug or post_type-slug (probably, it’s easier to fix and handle side-effects of renaming the taxonomy, I guess).

    2nd solution

    Also, I found one EXACT solution, you can find the details here. In the other words, you can set for your register_taxonomy() argument $args['query_var'] = false with which you disable query parameter speakers to act as taxonomy slug. Therefore, if you want to filter by taxonomy terms directly in URL / $_GET var, you will have to do some other magic. But, at least, you will remove collision between post_type and taxonomy names.

    Optionally, you will have to flush_rewrite_rules after that in whatever way you want:

    1. Add flush_rewrite_rules(); in functions.php, go to the site, refresh it several times, remove that line and save functions.php again.
    2. Go to WordPress admin -> Options -> Permalink and click save.

    I usually do both of it. Just in case.

    3rd solution

    Hook custom function to pre_get_posts(). With this method, you have to be careful in which case you will edit the query args. Put this in the functions.php.

    function preQueryAction( $query ) {
    
        // classic approach to avoid messing queries in Admin and custom queries.
        if(is_admin() or !$query->is_main_query()) return; 
        
        // selectively filter only if you are on CPT arhive
        if(is_post_type_archive()){
            $query->set( 'speakers', false );
        }
        
        return;
        
    }
    
    
    add_action( 'pre_get_posts', 'preQueryAction', 1 );
    
  2. I’m taking some shots in the dark, here.

    The first place I would look is your register_taxonomy call. You should make sure not to set the query_var option to false.

    register_taxonomy(
      'speakers',
      array('post'),
      array(
        'rewrite'                    => array( 'slug' => 'media-channel' ),
        'public'                     => true,
        'query_var'                  => 'speakers',
      )
    )
    

    With that in place you can be certain you can test the query using get_posts. This test would look like:

    $test_results = get_posts( array(
                          'post_type' => 'post', 
                          'numberposts' => -1,
                          'speakers' => 4,
                      ) );
    

    Did you get results? On looking at your example I have a strong suspicion that your taxonomy may be associated with attachments. If that’s the case I have had to do add “post_status” => “inherit”.

    $test_results = get_posts( array(
                          'post_status' => 'inherit',
                          'post_type' => 'attachment', 
                          'numberposts' => -1,
                          'speakers' => 4,
                      ) );
    

    How does this look to you? If you’re getting results here then maybe there’s something going on with the query parameters or rewrite rules.

    The codex register_taxonomy references the need to flush the rewrite rules if you use the ‘rewrite’ parameter.

     global $wp_rewrite;
     $wp_rewrite->flush_rules();
    

    Now that you’re fairly certain that you’re getting results from this query you can inspect the query that WordPress is building internally. This can be done with the excellent plug-in “Debug This” or using:

    global $wp_query;
    print_r($wp_query->query_vars);
    

    This will show the query that WordPress constructed using “?speakers=4”.