1

I am trying to create a custom homepage with multiple categories section. I know this is possible with WP_Query, but i don't want to make multiple db trips.

  1. I want to query posts (say 5 each) from specific categories (let's say from 4 different categories) by querying the database only once. something like >> new WP-Query (pass an array of cat ids or slug)

  2. After that while iside the loop, I want to sort the posts into 4 different sections categorywise, and provide different html markup for each category section. use some kind of if/else logic with rewind()

3
  • 1
    If you want 5 (or a specific) number of posts per category, then you need to make multiple WP_Query calls. Otherwise, you could use something like new WP_Query( 'cat' => '1,2,3,4' ) and then group the returned posts by their category upon displaying the posts.
    – Sally CJ
    Oct 19, 2020 at 7:32
  • Hey Sally, thanks for replying. Can you explain how to group the returned posts category-wise?
    – Kumar
    Oct 19, 2020 at 13:04
  • You'd put all the returned posts into an array, then loop through that array and sort the returned posts into 4 separate arrays based on their category ID using a foreach(). So something like foreach( $posts_array as $post_item ) and then use get_the_category() and compare the value against your 4 categories. If the value matches, add it to the category specific array, if not, move to the next one. Oct 19, 2020 at 15:42

1 Answer 1

0

As I said in the comments, if you want 5 (or a specific) number of posts per category, then you need to make multiple WP_Query calls. Otherwise, you could use something like new WP_Query( [ 'cat' => '1,2,3,4' ] ) and then group the returned posts by their category upon displaying the posts.

Working Examples

Revised so that categories without any posts do not get displayed. But see the note I put in Option 2 below.

Option 1: One WP_Query call with x posts per each category.

// Category IDs.
$cat_ids = [ 1, 2, 3, 4 ];

// For each category, query posts in that category, and just display them.
foreach ( $cat_ids as $id ) {
    $query = new WP_Query( [
        'cat'            => $id,
        'posts_per_page' => 5,
    ] );

    if ( $query->have_posts() ) {
        echo '<h2>' . esc_html( get_cat_name( $id ) ) . '</h2>';

        echo '<ul>';

        while ( $query->have_posts() ) {
            $query->the_post();

            echo '<li>';
            the_title( '<h3>', '</h3>' );
            // display other content you want
            echo '</li>';
        }

        echo '</ul>';
    }

    wp_reset_postdata();
}

Option 2: One WP_Query call for all the categories.

Note: With this option, there's no guarantee that all the categories are always available on each page/request. But the point is, the grouping. I.e. You'd get the posts displayed under their own category.

// Category IDs.
$cat_ids = [ 1, 2, 3, 4 ];

// Get all posts that are assigned to any of the above categories.
$query = new WP_Query( [
    'cat'            => implode( ',', $cat_ids ),
    'posts_per_page' => 10,
] );

// And then when displaying the posts, group them under their own category.
foreach ( $cat_ids as $cat_id ) {
    $list = '';

    if ( $query->have_posts() ) {
        while ( $query->have_posts() ) {
            $query->the_post();

            if ( has_category( $cat_id ) ) {
                $list .= '<li>';
                $list .= the_title( '<h3>', '</h3>', false );
                $list .= 'add other content you want here..';
                $list .= '</li>';
            }
        }
    }

    if ( $list ) {
        echo '<h2>' . esc_html( get_cat_name( $cat_id ) ) . '</h2>';
        echo '<ul>' . $list . '</ul>';
    }

    wp_reset_postdata();
}

I hope that helps, and just change the HTML to your liking.. Also, I'm assuming you're referring to the default category taxonomy; but for other taxonomies, you'd use has_tag() or has_term() in place of has_category(), and (for example, you can use) get_term_field() for getting the term/tag name.

3
  • That's working Sally. Thanks. However, there is a problem we didn't anticipate. The above code will fetch the latest 5 posts (post per page) and sort them out. But lets say those 5 post belong to just 1 category or maybe 2 categories, in that case the other categories sections remains empty. Is there a way to get 5 post per category?
    – Kumar
    Oct 20, 2020 at 5:55
  • I've revised my answer. Does the new code help?
    – Sally CJ
    Oct 20, 2020 at 10:56
  • 1
    I am going with the first option for now, since I want to display symmetrical (let's say 5 posts each) category-sections on my homepage. || The second option is more appropriate for something like sorting the n number of posts category-wise fetched by the WP_Query . But we can't make sure each section have equal no. of posts displayed. So, option 1 it is! Thanks for your time and input @Sally.
    – Kumar
    Oct 20, 2020 at 11:40

Your Answer

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

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