0

My goal is to display 5 different categories that is randomly arranged. I would like just to call them in one wp_query to lessen the load. My problem is the loop seems to be not showing the conditions and also the rewind posts dont follow the previous loop. Here is my code.

<?php
    $original = new WP_Query();
    $original ->query('cat=12,13,14&showposts=2');?>
<?php while ($original ->have_posts()) : $original ->the_post(); ?>
<!-- See if the current post is in category 3. -->
<?php if ( in_category('12') ) { ?>
<!--content-->
<?php } ?>
<?php endwhile; ?>

<?php rewind_posts(); ?>
<?php while (have_posts()) : the_post(); ?>
<?php if ( in_category('13') ) { ?>
<!--content-->
<?php } ?>
<?php endwhile; ?>

<?php rewind_posts(); ?>
<?php if ( in_category('14') ) { ?>
<?php while (have_posts()) : the_post(); ?>
<!--content-->
<?php endwhile; ?>

<?php rewind_posts(); ?>
<?php if ( in_category('15') ) { ?>
<?php while (have_posts()) : the_post(); ?>
<!--content-->
<?php } ?>
<?php endwhile; ?>
1

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) with posts_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.

  • Thanks but the category title is the only one i got working, it displayed 2 posts but they are all the same throughout the last category can you help me for the last time sorry. – Jayson Pimentel Sep 16 '13 at 14:10
  • Working cool and great! btw if i like to add random posts do i just need to edit the functions line $q = new WP_Query( array('posts_per_page' => 99, 'category__in' => $cats) ); and add 'orderby' => rand within this line or i have to also call it on the loop? And last how do you make the category name into a link to the cat page? Ihave this working for category link <a href="<?php echo $category_link; ?>" title="Category Name"><?php the_category(); ?></a> but its just repeated inside the loop? – Jayson Pimentel Sep 17 '13 at 4:49
  • 1
    Works pretty awesome!. How can i mark the question as accepted i cant see the button? – Jayson Pimentel Sep 17 '13 at 11:38
  • hello, i cant seem to capture title+firstpost+secondpost into one <ul><li>, im trying to align them vertically by twos, only the first posts and the title is included within the <ul> tag second post seems to be going into a separate <li> by itself. Also there is a sixth category appearing is it because some posts are on a dual category so its just for post with one category right? – Jayson Pimentel Sep 19 '13 at 6:22
  • As said in the 'Possible issues' function works only for posts with 1 cat. You should modify the function, essentially the part $cat = array_shift($cats); that take the first category should be replaced with a cycle through $cats array that check if the catagory is one of the desired cat. For the ul7li problem, notice that in the code there are 2 foreach loop, one cycle the categories, one tho posts. every code in second foreach will be repeated for every post, of course. – gmazzap Sep 19 '13 at 9:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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