How Do I List Posts in a Taxonomy by Year?
Listing posts by taxonomy term is a common feature requested when displaying blog posts. Sometimes you also want to separate those posts in sections by their year like this:
2017 News
2017 News Post
2017 News Post
2017 News Post
2016 News
2016 News Post
2016 News Post
2016 News Post
This can be achieved using a pretty simple function along with some nested foreach loops. Our function that is shown below gets all the arguments needed for your desired post type, taxonomy and taxonomy term. Once we have the arguments ready, it will loop through them and grab all the years and put them into an array.
function posts_by_year($postType, $taxonomy, $taxArgs) {
// array to use for results
$years = array();
// get posts from WP
$posts = get_posts(array(
'posts_per_page' => -1,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => $postType,
$taxonomy => $taxArgs,
'post_status' => 'publish'
));
// loop through posts, populating $years arrays
foreach($posts as $post) {
$years[date('Y', strtotime($post->post_date))][] = $post;
}
// reverse sort by year
krsort($years);
return $years;
}
With our function set up, we can call the function within a foreach loop on our desired template. Our first foreach loops over the years in the array to set our section headers. We then call another foreach loop to go over the posts within that year.
Function used in template:
<?php foreach(posts_by_year('post', 'category', 'news') as $year => $posts) : ?>
<h2><?php echo $year; ?></h2>
<?php foreach($posts as $post) : setup_postdata($post); ?>
<article class="post">
<h3 class="post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<span class="post-date"><?php echo get_the_date(); ?></span>
<p><?php the_excerpt(); ?></p>
<a href="<?php the_permalink(); ?>" class="">Read More</a>
</article>
<?php endforeach; ?>
<?php endforeach; ?>