I have an archive page showing all blog posts (in a specific category). With a growing number of posts, I want to separate these by publish year. For example (simplified), I'd like the following:


  • post
  • post
  • post


  • post

I'm testing this system by changing my oldest post's publish date to mid-2011. Currently the structure appears to be mostly working, but all posts are showing up under 2012, and none under 2011, despite the oldest post's publish date being set to 2011. To illustrate, I'm getting this:


  • post
  • post
  • post
  • post (2011 post)


I'm using the code below (some extra stuff has been removed to simplify, but it doesn't affect the result). Can anyone see why the old post is showing up under 2012 and not inside the 2011 <ul>? Thanks for your help.

<?php global $query_string; query_posts($query_string . '&posts_per_page=-1'); // Show all posts ?>
<?php if (have_posts() {
if (is_category('210')) { ?>
<div class="archive-posts-box">
    <?php $firstyear = '2011';
    $currentyear = date('Y');
    $postyear = get_the_time('Y', $post->ID);
    for ($i = $currentyear; $i >= $firstyear; $i--) { ?>
            <h4><?php echo $i ?></h4>
            <ul class="archive-posts">
            <?php while (have_posts() && $postyear == $i) {
                the_post(); ?>
                <li><span class="archive-post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></span><span class="archive-post-date"><?php the_time(get_option('date_format')); ?></span></li>
            <?php } // end while ?>
        <?php } // end for ?>        
</div><!-- .archive-posts-box -->
<?php } // end if (category)
} // end if (have_posts)
wp_reset_query() ?>
  • I see there are a couple of other questions related to this (e.g. wordpress.stackexchange.com/questions/46136/…), but I'm really hoping to use this code structure rather than change completely, as there is a bit of other stuff to incorporate once this is sorted. Ideally it would be great to make a small edit to this code if possible.
    – t-jam
    Dec 11, 2012 at 2:00

1 Answer 1


My original impression was that I believe that what is happening is that the Loop doesn't get incremented until the_post runs so your && $postyear == $i check is actually looking at the previous post not the current one. You are going to have to reorganize this to get that check after the Loop is incremented by the_post.

That said, I don't think I trust this logic at an even deeper level. You are setting $postyear before an enclosing loop ($postyear = get_the_time('Y', $post->ID);) so it isn't even effected by what happens with the_post. That worries me.

I know you don't want this much revision but for what it is worth I am thinking you need something more like:

 $oldyear = $postyear = get_the_time('Y', $post->ID);?>
 <h4><?php echo $postyear; ?></h4>
    <ul class="archive-posts"><?php
    while (have_posts()) {
      $postyear = get_the_time('Y', $post->ID);
      if ($oldyear != $postyear) {
    $oldyear = $postyear; ?>
    </ul><h4><?php echo $postyear; ?></h4><ul class="archive-posts">
      } ?>
    <li><span class="archive-post-title">
    <a href="<?php the_permalink(); ?>"><?php the_title(); ?>
    </a></span><span class="archive-post-date"><?php the_time(get_option('date_format')); ?></span></li><?php
    echo '</ul>';

I am going way, waaayy out on a limb with that. It has barely been tested but it should give you an idea.

  • Thanks @s_ha_dum, that worked swimmingly! I'd upvote your answer too but I don't have the rep.
    – t-jam
    Dec 11, 2012 at 3:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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