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.
WP_Query
calls. Otherwise, you could use something likenew WP_Query( 'cat' => '1,2,3,4' )
and then group the returned posts by their category upon displaying the posts.foreach()
. So something likeforeach( $posts_array as $post_item )
and then useget_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.