WordPress: Grouping posts by month/year

I have just been trying to work out how to group posts by year when displaying them in WordPress, something that could come in handy for a portfolio or a section on a website which has posts published infrequently. As I couldn’t find a definite solution elsewhere I thought I’d publish it here in case it helps someone else.

The first clue to how to do this came from Dev Lounge, although their solution uses “the_date” function which allows you to group multiple posts from a single day under one date listing.

However if you want to do this for groupings by year you need to apply a bit of simple PHP and variable assigning.

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

<?php
 // Assign the year to a variable
 $year = the_date('Y', '', '', FALSE);

 // If your year hasn't been echoed earlier in the loop, echo it now
 if ($year !== $year_check) {
 echo "<h2 class='year'>" . $year . "</h2>";
 }

 // Now that your year has been printed, assign it to the $year_check variable
 $year_check = $year;
?>

<div id="post-<?php the_ID(); ?>">
<!-- post content etc goes here  -->
</div><!-- end .post-wrap -->
<?php endwhile; ?>
<!-- previous next nav -->
<?php else : ?>
<!-- posts not found info -->
<?php endif; ?>

The same logic should apply to grouping by month – although you might need to tweak the code a little bit!

Comments

  • Paul Chamberlain

    Hey Alex,

    Great snippet – made it easy to do what I needed to do. However, I had a weird issue where some posts' dates were returning blank. This was fixed by changing "the_date" on line 5 to "get_the_date". Might be of use to someone in the future.

    Cheers,
    Paul

  • Paul Chamberlain

    Oh, actually I see why this was:

    "the_date" only returns the first instance of a date so, in my situation where I had multiple posts in one day, things got messed up.

    "get_the_date" returns the date no matter what.

    • Hmm, not sure why I haven’t replied to this. It’s a while since I used this function, but if it pops up again I’ll definitely check usage of get_the_date. I’d have to poke around to see if I have the same issue you had.

      Cheers!

  • SickHippie

    Still useful nearly 3 years on – thanks for this!

    • Woot! I’m so glad I’ve been putting functions up on this blog. Often saves my own ass when I can’t remember how I fixed an issue before 🙂

      Glad it was helpful!

      • SickHippie

        Indeed it was – I ended up modifying it to group by year with jQuery UI tabs. It took some working (and swapping out the_date() with get_the_date() because of the bug Paul pointed out), but this was what I needed to get going in the first place.  Many, many thanks!

        • Jo

          I’m currently trying to implement the same thing but I’m fairly new to PHP and was not sure how to do this. Would it be possible to share your code on this? I’m having a heck of a time implementing tabs with this.

  • Debbie Campbell

    What a HUGE help this was – thanks so much.

  • Dee

    Thank you! This is a very helpful snippet.
    Is there a way i can restrict this to show only posts related to some tags?

    • Hi Dee,

      I guess that would depend on your WP_Query object. The actual year division is just happening within the loop, after the actual query has been constructed, so once you’ve set up your query then you can just use this code inside the loop and you’ll be set.

      • Dee

        Thank you for coming so quickly… Since i’m not very familiar with
        code, i’m just being a magpie. Would there be a way to show the
        year-wise posts in a tag using a dropdown? Any tips/articles you could point me to would be great. Appreciate your help!

  • Thank you! This was very helpful. I got really close to what I’m looking for using your code. However, the one issue I’m running into is that I can only get one post to display for each year. I’ve posted my problem at Stack Overflow: https://stackoverflow.com/questions/28437200/wordpress-display-posts-by-year-set-in-advanced-custom-fields. Could you provide any insight?

    • Hey Alyssa,

      I posted an answer on Stack Overflow. I haven’t tested it but I’m pretty sure it’s right. You just need to keep the rendering of post titles etc outside of the if($year…) conditional.

  • Pingback: WordPress: Display Posts by Year Set in Advanced Custom Fields - Wordpress Helpdesk()