Your main problem is that the cat
param accept an integer (a term_id) as value, not a string of comma separed ids…
You have to use category__in
argument in your case.
Read here for more info.
Another problem is the use of showposts
argument: setting it to 2 you’ll get 2 posts in total, not 2 posts per category.
What I suggest you:
if functions.php
create a function like this:
function get_posts_for_cat_ordered( $cats = array(), $posts_per_cat = 2 ) {
if ( empty($cats) ) return false;
$args = array('posts_per_page' => 99, 'category__in' => $cats, 'orderby' => 'rand');
$q = new WP_Query( $args );
$posts_ordered = array();
$done = 0;
while ( $q->have_posts() ) : $q->the_post();
global $post;
$cats = get_the_category();
$cat = array_shift( $cats );
if ( ! isset($posts_ordered[$cat->slug]) )
$posts_ordered[$cat->slug] = array('term' => $cat);
if ( ! isset($posts_ordered[$cat->slug]['posts']) )
$posts_ordered[$cat->slug]['posts'] = array();
if ( count($posts_ordered[$cat->slug]['posts']) == $posts_per_cat ) {
$done++;
if ( $done == count($cats) ) return $posts_ordered;
continue;
}
$posts_ordered[$cat->slug]['posts'][] = $post;
endwhile;
wp_reset_postdata();
return $posts_ordered;
}
This function take an array of categories and a number of post you want retrieve for every category and return a multidimensional array with posts ordered per category.
After that use the function just created like so:
$cats = array(12, 13, 14);
$posts_per_category = 2;
$posts_ordered = get_posts_for_cat_ordered( $cats, $posts_per_category );
if ( ! empty($posts_ordered) ) { foreach ( $posts_ordered as $loop_data) {
// Example category heading
echo '<h2><a href="' . get_term_link($loop_data['term'], 'category') . '">' . $loop_data['term']->name . '</a></h2>';
global $post;
foreach ( $loop_data['posts'] as $post) {
setup_postdata($post);
?>
<!-- Example post content -->
<?php the_title(); ?><br />
<?php the_content(); ?><br />
<?php
}
wp_reset_postdata();
} }
Note that I’ve also
- changed the
showposts
argument (deprecated) withposts_per_page
- added
wp_reset_postdata
after the custom queries loop.
Possible issues:
If a post has more than one category this code may not worked as expected. But a little change in the get_posts_for_cat_ordered
function can solve this issue. However, if you don’t need this feature, leave code as is, because is more performant.
Another issues can happen if in the blog there is no enough posts for each wanted category inside the last 99 posts.
This is for the 'posts_per_page' => 99
argument in the query used in the get_posts_for_cat_ordered
function. I’ve used that number because is a reasonable high number, and if the blog has thousands of posts the fucntion will not affect performance.
Both these issues will not stop the function to work, but the showed posts can be less than expected if the described situations will occur.