Search code examples
phpwordpressarchivetaxonomy

Show all posts in a custom post type on a taxonomy archive page


I want to redirect my taxonomy archive pages to the main archive page for the post type, displaying all the posts and then filtering them rather than only displaying only the ones matching the taxonomy term. I believe I need to alter the loop using pre_get_posts but I can't remove the taxonomy. I have tried:

if ( !is_admin() && $query->is_main_query() && $query->is_tax()) {
        $query->set( 'tax_query',array() ); 
}

if ( !is_admin() && $query->is_main_query() && $query->is_tax()) {
        $query->set( 'tax_query','' );  
}

I've read solutions for changing tax_query, but not removing it.

Alternatively, is there a better way to redirect a taxonomy archive to a post type archive? (I've searched for this but found nothing.)


Solution

  • If you want to redirect a taxonomy page to it's post type archive, you might try something like below.

    Careful, though! There's an assumption implicit in your post that a WP_Taxonomy has a single post_type mapped to it. In practice, you can have your taxonomies map to as many post_type objects as you like. The code below redirects taxonomy pages to an associated custom post type archive wether or not it's the only one that taxonomy applies to!

    Additionally – make sure that your custom post type's got the has_archive key set to true in it's register_post_type args!

    <?php
    // functions.php
    
    function redirect_cpt_taxonomy(WP_Query $query) {
        // Get the object of the query. If it's a `WP_Taxonomy`, then you'll be able to check if it's registered to your custom post type!
        $obj = get_queried_object();
    
        if (!is_admin() // Not admin
            && true === $query->is_main_query() // Not a secondary query
            && true === $query->is_tax() // Is a taxonomy query
        ) {
            $archive_url = get_post_type_archive_link('custom_post_type_name');
    
            // If the WP_Taxonomy has multiple object_types mapped, and 'custom_post_type' is one of them:
            if (true === is_array($obj->object_type) && true === in_array($obj->object_type, ['custom_post_type_name'])) {
                wp_redirect($archive_url);
                exit;
            }
    
            // If the WP_Taxonomy has one object_type mapped, and it's 'custom_post_type'
            if (true === is_string($obj->object_type) && 'custom_post_type_name' === $obj->object_type) {
                wp_redirect($archive_url);
                exit;
            }
        }
    
        // Passthrough, if none of these conditions are met!
        return $query;
    }
    add_action('pre_get_posts', 'redirect_cpt_taxonomy');