Adventures With The Wordpress Loop: Sticky Articles

Posted on Sunday, February 18th, 2007

Having decided to mix up my front page with a latest article section, I then had to work out how to manipulate the Wordpress Loop in order to display what I wanted. It took quite a lot of thinking, one wrong (oh so wrong) attempt and then I cracked it. Please note, this involves playing about with the index.php file in your theme, if you don’t want to spoil anything, please back it up! Now, here’s how to do it:

The Normal Loop

The wordpress default theme starts the loop with

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

and ends with

<?php endwhile; ?>

In between are the functions to dislpay your posts, their titles, the permalink, the date, the list goes on. Editing the bit inside changes how each post is displayed, but it can’t change which posts are displayed. For that you need to play with the loop itself.

Once, Twice, Three Times WP_Query

Remember that I wanted the latest post, then the latest article, then the remaining recent posts. To do this, I have to, in effect, run three loops. The first will select my latest post.

<?php $my_query = new WP_Query('showposts=1');
while ($my_query->have_posts()) : $my_query->the_post();
$do_not_duplicate = $post->ID; ?>

// do stuff

<?php endwhile; ?>

The first line starts a new query with the parameter that only one post is shown. The second line is the equvalent of the first line of the normal loop and the third line will become clear soon. The second loop starts off again in a similar way, creating a new query, this one is for the latest article though.

<?php $my_query = new WP_Query('showposts=2&cat=31');
while ($my_query->have_posts()) : $my_query->the_post();
if ( $post->ID == $do_not_duplicate ) continue;
update_post_caches($posts);
$do_not_duplicate = $post->ID; ?>

// do stuff

<?php break; ?>
<?php endwhile; ?>

The first line picks the new query again, this time choosing to show 2 posts (more on that in a minute) and picking them from category 31, my Articles category. The third line is where this starts to get interesting. This checks that the selected article hasn’t already been posted in the first loop. If it has, the continue action moves the loop onto the next article. This forms the reason to why I made the query choose two posts from the articles category. I only want to display one, so if the first post is not the same as the first article, then the break at the end of the loop jumps it straight out before it can loop round for the second article.

The update_post_caches($posts) is straight out of the codex, to ensure that plugins work happily with these multiple loops. Also, once the code selects the correct article to display it notes the ID of the post in the $do_not_duplicate variable, but more on that after we see the third loop:

<?php query_posts('showposts=4&offset=1'); ?>

<?php if ( have_posts() ) :
while ( have_posts() ) : the_post();
if( $post->ID == $do_not_duplicate) continue;
update_post_caches($posts); ?>

// do stuff

<?php endwhile; ?>

The final loop kicks off with the first line selecting what we want to display using the normal query_posts call. In this case, we show 4 posts, but not the first one by offsetting by one. The next two lines are straight out of the normal loop as this is the one we are running now. Line four ensures that we do not display the article we fetched in the second loop, the first post is already missed by the offset in the query. Finally we update_post_caches($posts) once more in order to be friendly to plugins.

That’s It

If you want to display a latest article of some sort, all you have to do now is copy the above code and insert the relevant template tags that you want to use where it says “do stuff”. I’d love to know if this helps anyone, either in their understanding of the loop or as a solution to the problem I first posed. This way worked for me, but if there is a better way, I would love to know!

Disclaimer: This worked for me using Wordpress 2.1 and my own theme. Please back up your theme before trying this, just in case. If you have any difficulties, please leave me a comment and I will respond.

Thanks goes to whoever wrote the codex article on the loop and Maxpower and Shaun Andrew’s articles on sticky posts which helped me along brilliantly.

If you enjoyed this post, why not subscribe to Unintentionally Blank

Comments

  1. Shaun Andrews Says:

    Glad I could help!


  2. Phil Says:

    Hey Shaun, thanks for dropping by. Your post on this made things clear. Clearer than the codex article anyway, but you have to go through all of that to get the hang of it too!
    Thanks again!


  3. Laura Says:

    Wow! You’re a little over my head on this. Thanks for bringing this to my attention.


  4. Phil Says:

    Sorry Laura!

    It was certainly interesting for me learning how that part of WordPress worked and how to manipulate it.

    If you ever wanted an original front page for displaying sticky articles, at least you know who to ask now!


  5. Pingback by Gack Ink BYOB

  6. Pingback by reportaz.gr | Δοκιμή |

  7. John Says:

    Man, this almost did it. Almost, not quite.

    After processing the third loop, I still have a duplicate post from the first loop.

    Any ideas?


  8. Joe Says:

    You’re awesome dude. Got into some trouble because of the use of tags, categories, an array and a sort-of complicated front page…but its all done!

    Thanks.


  9. Emma Says:

    Hi Phil

    I think this is probably great, but it’s a bit over my head I’m afraid:-) I’d like to have only one post showing on my front (home) page - any chance you could help me understand what code I would need to put (and where) just for this?

    Thanks
    Emma


Leave a Comment