A fresh mix of code snippets and tutorials

WordPress Navigation Links for Monthly Archives

Archives that are easy to navigate make your WordPress-powered site that much more awesome. There are plenty of great strategies for increasing the usefulness of your post archives. For example, this quick tutorial provides some custom functions that display monthly navigation links. So you can display “Previous Month” and “Next Month” links on monthly archive views (via your theme template). This makes it easy for visitors to surf your archives by month, which can be super useful for sites with a lot of post content. I used this technique for a previous theme at Perishable Press.

The Code

To implement navigation links for monthly archives, add the following code to your theme’s functions.php file (or add via simple plugin).

function shapeSpace_next_month_link($label = 'Next Month') {
	echo shapeSpace_get_month_link($label, false);

function shapeSpace_previous_month_link($label = 'Previous Month') {
	echo shapeSpace_get_month_link($label);

function shapeSpace_get_month_link($label, $previous = true) {
	$archive_month = shapeSpace_get_date($previous);
	$link = '';
	if ($archive_month) {
		$year = isset($archive_month[0]) ? $archive_month[0]->year : '';
		$month = isset($archive_month[0]) ? $archive_month[0]->month : '';
		$full_month = date('F', strtotime($year .'-'. $month));
		$label = str_replace(array('%month', '%year'), array($full_month, $year), $label);
		$link = '<a href="'. get_month_link($year, $month) .'">'. $label .'</a>';
	return $link;

function shapeSpace_get_date($previous = true) {
	global $wpdb;
	$date = '';
	if (is_archive() && is_month()) {
		$year  = get_query_var('year');
		$month = get_query_var('monthnum');
		$month = str_pad($month, 2, '0', STR_PAD_LEFT);
		if ($previous) {
			$first_day = $year .'-'. $month .'-01 00:00:00';
			$post_date = " AND post_date < '". $first_day ."'";
			$order = 'DESC';
		} else {
			$last_day = date('Y-m-d H:i:s', strtotime('first day of next month'. $year .'-'. $month));
			$post_date = " AND post_date >= '". $last_day ."'";
			$order = 'ASC';
		$query = "SELECT YEAR(post_date) AS `year`, 
				  MONTH(post_date) AS `month`, count(ID) as posts FROM ". $wpdb->posts ." 
				  WHERE post_type = 'post' AND post_status = 'publish'". $post_date ." GROUP BY YEAR(post_date), 
				  MONTH(post_date) ORDER BY post_date ". $order ." LIMIT 0, 1";
		$date = $wpdb->get_results($query);
	return $date;

No modifications are required. Simply add, save, and upload to the server. Then proceed to the next section for usage infos.


Once the previous code is added to your site, you can display previous/next-month navigation links via the following template tags:

<?php shapeSpace_previous_month_link('&larr; %month %year'); ?>

<?php shapeSpace_next_month_link('%month %year &rarr;'); ?>

Each tag accepts a “label” argument, so you can customize the link text as desired. Note that you can use %month and %year to display the month and year for the current monthly archive view.

Bonus: Optional

Normally monthly archives display paged results. So each month archive page will display a limited number of posts, along with navigation links so you can view previous and next posts for that month archive. This code snippet can be added to your theme if you want to display all posts on each month archive page.

function shapeSpace_monthly_nav($query) {
	if (!is_admin() && $query->is_main_query()) {
		if (is_archive() && $query->is_month()) {
			$query->set('nopaging', true);
add_action('pre_get_posts', 'shapeSpace_monthly_nav');

As before, no editing is required. You simply add the function and each month archive page will display all included posts (instead of paging the results). So probably best to only add this code if you don’t post a LOT of posts each month.

Learn more

WordPress Themes In Depth