1

I'm using the following code to display posts from a specific category, in a grid layout, on my home page. It works exactly how I want it to, but I keep reading that I shouldn't ever use query_posts. How can I achieve the same results, without using query_posts?

Also, I will eventually need to display posts from maybe ten different categories on the home page - using this exact same grid layout. Would it cause issues if I duplicated all of the code below for each category, or is there a more efficient way to do this?

Any advice would be greatly appreciated - as you will probably be able to work out from my code and questions, I'm fairly new to WordPress development :)

<?php
$counter = 1; //start counter
$grids = 3; //Grids per row
global $query_string; //Need this to make pagination work

/*Setting up our custom query (In here we are setting it to show 3 posts per page and eliminate all sticky posts) */
query_posts( array('posts_per_page'=>3, 'category_name'=>'Mobile') );

if(have_posts()) :  while(have_posts()) :  the_post(); 
?>

<?php
//Show the left hand side column
if($counter == 1 || $counter == 2) :
?>
            <div class="col-cat3">
                <div class="entry-featured"><?php x_featured_image(); ?></div>
                <div class="col-cat-pic"><?php echo get_avatar( get_the_author_meta('ID'), 40); ?></div>
                <div class="hero-info">
                <h3><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h3>
                <p class="p-meta"><?php the_author_posts_link(); ?>  /  <?php the_time('m.d.y'); ?></p>
                </div>
            </div>
<?php
//Show the right hand side column
elseif($counter == $grids) :
?>
             <div class="col-cat3-last">
                <div class="entry-featured"><?php x_featured_image(); ?></div>
                <div class="col-cat-pic"><?php echo get_avatar( get_the_author_meta('ID'), 40); ?></div>
                <div class="hero-info">
                <h3><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h3>
                <p class="p-meta"><?php the_author_posts_link(); ?>  /  <?php the_time('m.d.y'); ?></p>
                </div>
            </div>
<?php
$counter = 0;
endif;
?>
<?php
$counter++;
endwhile;
//Pagination can go here if you want it.
endif;
?>
2

I think the general suggestion is to use WP_Query instead of query_posts partly because query_posts used WP_query in a simplified way and can cause problems down the road. So for sure check out the WP_Query page, specifically the Multiple Loops example: http://codex.wordpress.org/Class_Reference/WP_Query#Multiple_Loops

So the code using WP_Query would look something like this:

<?php
$counter = 1; //start counter
$grids = 3; //Grids per row
global $query_string; //Need this to make pagination work

/*Setting up our custom query (In here we are setting it to show 3 posts per page and eliminate all sticky posts) */
$query1 = new WP_Query( array('posts_per_page'=>3, 'category_name'=>'Mobile') );

if( $query1->have_posts()) :  while( $query1->have_posts()) : $query1->the_post(); 

    if( $counter == $grids ) : 
        $counter = 0; // Reset counter ?>
        <div class="col-cat3-last">
    <?php else: ?>
        <div class="col-cat3">
    <?php endif; ?>

        <div class="entry-featured"><?php x_featured_image(); ?></div>
        <div class="col-cat-pic"><?php echo get_avatar( get_the_author_meta('ID'), 40); ?></div>
            <div class="hero-info">
                <h3><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h3>
                <p class="p-meta"><?php the_author_posts_link(); ?>  /  <?php the_time('m.d.y'); ?></p>
            </div>
        </div>
<?php
$counter++;
endwhile;
//Pagination can go here if you want it.
endif;
wp_reset_postdata(); // Reset post_data after each loop
?>

Notice the same $args can be used in the WP_Query. Also notice the addition of $query1-> in the loop setup. Just change $query1 to $query2 when you copy paste this code and most likely change the category_name in the query args to match your category.

I also cleaned up some repetative code as it looked like the only difference was the '-last' added to the wrapping div class. So instead of having extra code to update in the future you could just use this.

I also added wp_reset_postdata(); in the end there to be safe and clear/reset the post data.

Let me know if you have any questions or concerns.

3
  • 1
    Thanks for that Sean, works perfectly. Hope you don't mind me asking a follow up question. If I wanted to use that same layout for my category page, what would I need to change? At the moment my category page shows all the posts - not just the category you click through from. – Paul Dixon Mar 16 '15 at 18:50
  • Yeah, No prob. ... If you wanted to use this same layout for a Category Page just remove the WP_Query line completly and the $query1-> from in front of the 2 have_posts() and the_post() (this makes it like a regular loop... ie codex.wordpress.org/The_Loop#Loop_Examples ) ... remove the wp_reset_postdata() at the bottom and the global query_string at the top. Then I'd suggest to save it as category.php if you don't already have one. ... Also check out this page: wphierarchy.com and follow the Archive Page -> Category Page to see what your theme is using for Category Page. – Sean Grant Mar 16 '15 at 19:28
  • Fantastic - thanks again! I saved it as category.php as recommended, and will definitely check out the links you provided. – Paul Dixon Mar 16 '15 at 20:10

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.