Filtering posts from different categories into different section by doing WP_Query only once

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()

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x