Ask your WordPress questions! Pay money and get answers fast! (more info)

Multiple loops - Workaround WordPress

Hi, I'm working on a new frontpage layout with multiple loops, and are trying to figure out how to do this the best way. Currently i feel this is just too many loops to run at once, and hope someone could help me do this in a more efficient way.

Heres the thing:

This is for a small blogg/newssite.

I got 4 different tags/categories i need to pull data from - A B C D.

They will be wrapped into 4 different columns/rows - laying side by side.

Each column will be setup the same way, and here's what it looks like:

1) Most popular post.
2) Latest post 1.
3) Column break - full width box for ads etc.
4) Latest post 2.
5) Latest post 3.
6) Column break - full width box for ads etc.
7) Latest post 4.
8) Latest post 5.

(See image for a visual example)

For me to acomplish this, i would need to do 4 wordpress queries for each category row. That would mean 16 queries together to acomplish this for all 4 categories!

Is it just me, or is this just too many loops to run at once?

I'm thinking of ways to do this more effecient - less loops - but still the same result.

Any ideas / examples?

Howie

Answers (6)

2013-08-19

Daniele Raimondi answers:

You just need to do 2 loops for each category, one for the most viewed and one to show the last 3 posts.

For the last 3 posts
<?php
$catquery = new WP_Query( 'cat=3&posts_per_page=3' );
while($catquery->have_posts()) : $catquery->the_post();
?>
<ul>
<li><h3><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h3>

<ul><li><?php the_content(); ?></li>
</ul>
</li>
</ul>
<?php endwhile; ?>

Just change cat id in the WP_QUERY, or you can use category_name parameter and use the category slug instead of category ID, as stated here
[[LINK href="http://codex.wordpress.org/Class_Reference/WP_Query#Category_Parameters"]]http://codex.wordpress.org/Class_Reference/WP_Query#Category_Parameters[[/LINK]]

For the most viewed without a plugin you can take a look here
[[LINK href="http://www.wpbeginner.com/wp-tutorials/how-to-track-popular-posts-by-views-in-wordpress-without-a-plugin/"]]http://www.wpbeginner.com/wp-tutorials/how-to-track-popular-posts-by-views-in-wordpress-without-a-plugin/[[/LINK]]


haurs comments:

Hi Daniele, and thanks for your reply.

I can't seem to understand how this would work when i have to split the query into several columns like i showed in the picture.

It's like this:

Most populare.
Post 1.
Column break.
Post 3-4.
Column break.
Post 5-6.
Column break.

How can i use your code when i have to break the output like showed above?

Maybe I'm over-complicating things.


Daniele Raimondi comments:

ah ok, you can then uset get_posts instead of WP_Query; get_posts returns queried posts in an array, so you can then make everithing you want on it (like extract only the items you need where you need them):

<?php
$args = array( 'posts_per_page' => 3, 'category' => 1 );
$myposts = get_posts( $args );
?>


Then you can output a single post where you need, like this:

<?php setup_postdata( $myposts[0] ); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>


As you can see, setup_postdata permits to use the usual in-loop functions to output post data


Daniele Raimondi comments:

Arghh!
REMEMBER: use wp_reset_postdata(); every time you finish to print each post and before you can use setup_postadata() again!

2013-08-19

Liam Bailey answers:

Hi Howie,

You dont need to do 16 queries, only 4 using get_posts. get_posts() uses almost all the same arguments as WP_Query but it stores an array of post objects. So, above the column break you would do:
$posts_cat_a = get_posts('cat=4');
//where cat = id of Category A from your example, or use a tax_query and use its slug, whatever way you want to achieve it
$i = 0;

while($i <=1) { //show 2 posts
?><h2><?php echo $posts_cat_a[$i]->post_title; ?>
<a href='<?php echo get_permalink($posts_cat_a[$i]->ID); ?>><?php echo $posts_cat_a[$i]->post_title; ?></a><?php
}
//and so on for the rest of the columns and then after the column break just do

$i = 2;
while ($i < count($posts_column_a)-1) {
<h2><?php echo $posts_cat_a[$i]->post_title; ?>
<a href='<?php echo get_permalink($posts_cat_a[$i]->ID); ?>><?php echo $posts_cat_a[$i]->post_title; ?></a><?php
}


haurs comments:

Hi Liam and thank you for your reply.

This looks like a good way to accomplish what i'm trying to do.

The code keeps on looping tho and won't stop with only showing 2 posts. It echo's the same results and keeps on echoing out.

Will need to tweak this one to see if can solve the issue.

Thanks again!


Liam Bailey comments:

Apologies,

I never saw your reply till now, I have made a mistake in the code, which is why it keeps looping, please use this instead:

$posts_cat_a = get_posts('cat=4');

//where cat = id of Category A from your example, or use a tax_query and use its slug, whatever way you want to achieve it

$i = 0;

while($i <= 1) { //show 2 posts

?><h2><?php echo $posts_cat_a[$i]->post_title; ?>

<a href='<?php echo get_permalink($posts_cat_a[$i]->ID); ?>><?php echo $posts_cat_a[$i]->post_title; ?></a><?php
$i++;
}

//and so on for the rest of the columns and then after the column break just do



$i = 2;

while ($i <= 3) {

<h2><?php echo $posts_cat_a[$i]->post_title; ?>

<a href='<?php echo get_permalink($posts_cat_a[$i]->ID); ?>><?php echo $posts_cat_a[$i]->post_title; ?></a><?php
$i++;
}

And in next column:

while ($i < count($posts_column_a)-1) {

<h2><?php echo $posts_cat_a[$i]->post_title; ?>

<a href='<?php echo get_permalink($posts_cat_a[$i]->ID); ?>><?php echo $posts_cat_a[$i]->post_title; ?></a><?php
$i++;
}

2013-08-19

Just Me answers:

Just a tip on coding.
In coding it is best not to repeat yourself (the DRY principle - Don't Repeat Yourself)

If you have just 4 categories you could do something like

<?php
$category_ids = get_all_category_ids();
foreach($category_ids as $cat_id) {
//your code goes here, using $cat_id where the id of the category is needed
}
?>


If you have more than 4 categories but only want 4 of them included in this page you can replace

$category_ids = get_all_category_ids();

with

$category_ids = array(1,3,8,7);

2013-08-19

Sabby Sam answers:

Hi Haurs,
I Have done the same thing with one of my project, below is the example
It pull the article with the given query query_posts('featured_area=1&posts_per_page=1'); from the template file <?php include(TEMPLATEPATH . '/includes/recent-cat.php'); ?>
I have done the same thing with alternate way,
by writing down the some function in function.php.
It display four different article, I could show you the live site, if you need I will pm you.

<div id="from-categories" class="clearfix">
<?php $last = false; ?>
<?php $headingColor = 'orange'; ?>
<div class="recent-cat first">
<?php $cat_option='thesource_home_cat_one'; ?>
<?php $tcatname=(esc_html(get_option($cat_option))); ?>
<?php $category_id = get_cat_ID( $tcatname );
$category_link = get_category_link( $category_id );
?>
<?php query_posts('featured_area=1&posts_per_page=1');
while (have_posts()) : the_post(); ?>
<?php include(TEMPLATEPATH . '/includes/recent-cat.php'); ?>
<?php endwhile; wp_reset_query(); ?>
</div> <!-- end .recent-cat-first -->

<?php $headingColor = 'green'; ?>
<div class="recent-cat">
<?php $cat_option='thesource_home_cat_two'; ?>
<?php $tcatname=(esc_html(get_option($cat_option))); ?>
<?php $category_id = get_cat_ID( $tcatname );
$category_link = get_category_link( $category_id );
?>
<?php query_posts('featured_area=2&posts_per_page=1');
while (have_posts()) : the_post(); ?>
<?php include(TEMPLATEPATH . '/includes/recent-cat.php'); ?>
<?php endwhile; wp_reset_query(); ?>
</div> <!-- end .recent-cat -->

<?php $headingColor = 'light-blue'; ?>
<div class="recent-cat">
<?php $cat_option='thesource_home_cat_three'; ?>
<?php $tcatname=(esc_html(get_option($cat_option))); ?>
<?php $category_id = get_cat_ID( $tcatname );
$category_link = get_category_link( $category_id );
?>
<?php query_posts('featured_area=3&posts_per_page=1');
while (have_posts()) : the_post(); ?>
<?php include(TEMPLATEPATH . '/includes/recent-cat.php'); ?>
<?php endwhile; wp_reset_query(); ?>
</div> <!-- end .recent-cat -->

<?php $headingColor = 'blue'; ?>
<div class="recent-cat last">
<?php $last = true; ?>
<?php $cat_option='thesource_home_cat_four'; ?>
<?php $tcatname=(esc_html(get_option($cat_option))); ?>
<?php $category_id = get_cat_ID( $tcatname );
$category_link = get_category_link( $category_id );
?>
<?php query_posts('featured_area=4&posts_per_page=1');
while (have_posts()) : the_post(); ?>
<?php include(TEMPLATEPATH . '/includes/recent-cat.php'); ?>
<?php endwhile; wp_reset_query(); ?>
</div> <!-- end .recent-cat -->
</div> <!-- end #from-categories -->

2013-08-19

Krum Cheshmedjiev answers:

I would suggest my plugin [[LINK href="http://krumch.com/2012/09/27/kc-taxonomy-list/"]]KC Taxonomy List[[/LINK]]. It works both by [short codes] and functions, you will need only to set templates. And queries...

2013-08-19

Abdelhadi Touil answers:

Hi.
For the "most viewed/popular poast" do you use a specific plugin for display views posts? Or you want to display most popular post by comments?
For other sections they are simple, we can just use a custom WP_Query with "offset" argument to split the WP_Query before and after the ads section.


haurs comments:

Hi Abdelhadi,

Thank you for your reply. I haven't decided if i will base the popular post upon comments/view/ or sticky posts, but that won't be a problem.

The problem for me is to keep the amounts of WP queries as low as possible but still work with the ads section in between.

You recommended using "offset" argument to split the query before and after the ads section, and that sounds exactly like what I'm trying to do.

Can you give an example of how this can be accomplished?


Abdelhadi Touil comments:

What I do in such situation is like this code:

<!-- A query for the latest post from category A with catAID ID -->
<?php $latestA = new WP_query('posts_per_page=1&cat=catAID'); ?>
<?php while ($latestA->have_posts()) : $latestA->the_post(); ?>
Your code here
<?php endwhile; ?>

<!-- Your ads section goes here -->

<!-- A query for the other 2 latest posts from category A with catAID ID except the latest post (in previous query) -->
<?php $latestA = new WP_query('offset=1&posts_per_page=2&cat=catAID'); ?>
<?php while ($latestA->have_posts()) : $latestA->the_post(); ?>
Your code here
<?php endwhile; ?>


Hope it's clear. You can read more about WP Query and its arguments (including offset argument) at WordPress Codex:

[[LINK href="http://codex.wordpress.org/Class_Reference/WP_Query"]]http://codex.wordpress.org/Class_Reference/WP_Query[[/LINK]]

and here is a nice code to display most popular posts in the last 30 days without a Plugin:

[[LINK href="http://wpmu.org/daily-tip-display-your-most-popular-posts-in-the-last-30-days-without-a-plugin/"]]http://wpmu.org/daily-tip-display-your-most-popular-posts-in-the-last-30-days-without-a-plugin/[[/LINK]]

Good luck!


haurs comments:

Thanks Abdelhadi. So this means you create a new WP_query for each column right?

If that's right this would result in about 12 WP_queries in my case. 4 queries for each category in first column row * 3 rows with ads between.

Or does "$latestA = new WP_query" both before and after ads section count only as 1 query request? - meaning I could use the same query for as many rows down the page as i want without it having to query the database more than once?


Abdelhadi Touil comments:

I'm not sure about this point, but I don't see any other ways to do so without using such queries, although I think you are right. What if we use rewind_posts() function? I'v just searched and it sounds great, read here:

[[LINK href="http://digwp.com/2011/09/3-ways-to-reset-the-wordpress-loop/#rewind_posts"]]http://digwp.com/2011/09/3-ways-to-reset-the-wordpress-loop/#rewind_posts[[/LINK]]

What do you think?
For me I just use queries, and so they are doing here:

[[LINK href="http://wp.tutsplus.com/tutorials/theme-development/how-to-create-a-homepage-with-multiple-listings-using-custom-queries/"]]http://wp.tutsplus.com/tutorials/theme-development/how-to-create-a-homepage-with-multiple-listings-using-custom-queries/[[/LINK]]

But I think it's very interesting if we can go with an alternative solution to reduce the number of queries.