1
votes

I've got two custom post types, for example 'Cars' and 'Bikes'. I've used Wordpress's default category to categorise the posts from the two post types. Let's say for example the categories are 'Red', 'Blue' and 'Black'.

What I'm trying to achieve here is that when I go to the category page for 'Red', I want to see the 'Cars' and the 'Bikes' that are categorised under 'Red'. I'm using the category.php and this is the query that I'm trying to run:

$car_args = array(
                    'posts_per_page'   => -1,
                    'orderby'          => 'date',
                    'order'            => 'DESC',
                    'post_type'        => 'cars',
                    'post_status'      => 'publish',
                    'cat'              => $cat
                );

                // The Query
                $car_query = new WP_Query( $car_args );

                // The Loop
                if ( $car_query ->have_posts() ) {
                echo "<h3>Cars</h3>";
                    while ( $car_query->have_posts() ) {
                        $car_query->the_post();
                        echo get_post_type() . '<a href="'. get_permalink() .'">' . get_the_title() . '</a><br />';
                    }
                } else {
                    // no posts found
                }

$bikes_args = array(
                    'posts_per_page'   => -1,
                    'orderby'          => 'date',
                    'order'            => 'DESC',
                    'post_type'        => 'bikes',
                    'post_status'      => 'publish',
                    'cat'              => $cat
                );

                // The Query
                $bikes_query = new WP_Query( $bikes_args );

                // The Loop
                if ( $bikes_query ->have_posts() ) {
                echo "<h3>Bikes</h3>";
                    while ( $bikes_query->have_posts() ) {
                        $bikes_query->the_post();
                        echo get_post_type() . '<a href="'. get_permalink() .'">' . get_the_title() . '</a><br />';
                    }
                } else {
                    // no posts found
                }

                /* Restore original Post Data */
                wp_reset_postdata();

The $cat in the query gets the category id of 'Red' category. Both these queries are correctly restricting the posts by the 'Red' category but posts from both the 'Cars' post type and 'Bikes' post type are showing up even though I've tried to restrict by post type. I've read in a few articles that Wordpress ignores the post type args on the category page. Is this true and if it is, is there a workaround for this?

1
Drop you custom query, go back to the default loop, and then use pre_get_posts to set your post type and custom posts per page to your category archive pagePieter Goosen
Hi @PieterGoosen. Thanks, will try that. But if I do it this way, will I have to have category-{colour}.php for every colour that I have in the categories?NJT
Nope, just one categoty.php will be finePieter Goosen
I'm busy on another question, so just give me an hour or so :-)Pieter Goosen
No problem. :) I will try and figure this out in the meanwhile.NJT

1 Answers

1
votes

What you are trying to do is possible with one query only, and only with the main query without any custom queries.

First of all, lets first add your custom post types to your category page. By default, custom pist types are excluded from category pages. So we need to add this manually to the main query arguments via pre_get_posts. Add the following to your functions.php: (CAVEAT: Untested and also requires PHP 5.3+)

add_action( 'pre_get_posts', function ( $q )
{
    if ( !is_admin() && $q->is_main_query() && $q->is_category() ) {
        $q->set( 'post_type', array( 'post', 'cars', 'bikes' ) ); // Change this according to your post types
        $q->set( 'nopaging', true ); // This will get all posts, same as posts_per_page=-1
    }
});

You should now have all posts from a clicked category is your set post types on your category pages.

Next, wee need to sort out your loops. Delete all your custom queries in category.php and replace it with the default loop. As you would want two block ordered by post type, we will use rewind_posts() so we can run the loop twice

if ( have_posts() ) {
    while ( have_posts() ) {
    the_post();

        if ( $post->post_type == 'cars' ) { //Change accordingly to only show cars in this loop

            // Your loop

        }
    }

    rewind_posts();

    while ( have_posts() ) {
    the_post();

        if ( $post->post_type == 'bikes' ) { // Change accordingly to only show bikes

            // Your loop

        }
    }
}

This should now display your posts in two block sorted by post type