0

I have registered the two following custom post types:

function dogs() {

    $labels = array(
        'name' => 'Dogs'
    );

    $args = array(
        'labels' => $labels, 
        'public' => true,
        'has_archive' => true,            
        'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' )
    );

    register_post_type( 'dog', $args );
}

function cats() {

    $labels = array(
        'name' => 'Cats'
    );

    $args = array(
        'labels' => $labels, 
        'public' => true,
        'has_archive' => true,
        'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' )
    );

    register_post_type( 'cat', $args );
} 

In the archive page for the 'dog' post type (mysite.com/dog), I want to display posts that use both the 'dog' and the 'cat' post type. So I've created a custom template called archive-dog.php and altered the main query like this:

add_action( 'pre_get_posts', 'cats_and_dogs' ) );

function cats_and_dogs( $query ) {
    if( ! is_admin() && is_post_type_archive( 'dog' ) ) {
        if( $query->is_main_query() ) {  
            $query->set( 'post_type', array( 'dog', 'cat'  ) );
            $query->set( 'posts_per_page', 4 );
            $query->set( 'post_status', 'publish' );  
            $query->set( 'post__not_in', get_option( 'sticky_posts' ) ); 
        } 
    }         
}

When I visit mysite.com/dog, I would expect Wordpress to automatically pick up archive-dog.php and display both 'dog' and 'cat' posts. Instead, while it does display both 'dog' and 'cat' posts, it does not pick up the archive-dog.php but falls back to archive.php. If I remove the 'cat' post type from the altered main query and only leave 'dog', everything works fine. How can I have both both post types and my custom archive template?

  • Have you tried reversing the order for the post_types? It's a hack but worth a try. – Welcher Nov 21 '17 at 13:56
2

You can manage this via the template_include hook.

add_filter( 'template_include', 'cats_and_dogs_living_together', 99 );

function cats_and_dogs_living_together( $template ) {

    if ( is_post_type_archive( array ( 'cat', 'dog' ) ) ) {
        $new_template = locate_template( array( 'archive-dog.php' ) );
        if ( '' != $new_template ) {
            return $new_template;
        }
    }
    return $template;
}

Hope this helps!

  • Thank you, yes, this works. But now I wonder, was the issue I was having an intended Wordpress behavior? In other words, is it "normal" that Wordpress doesn't pick up the right template when multiple custom post types are specified? – grazianodev Nov 21 '17 at 14:30
  • I think it's because the rewrite found cat before dog and when it didn't find a matching archive-cat.php, the templating system did what it is supposed to do an fell back to archive.php. Might be work reversing the order in the query just to see if that makes a difference – Welcher Nov 22 '17 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.