Dissecting WordPress Themes Part 8: Date Hierarchy

In this article, we continue looking at the WordPress archives by demonstrating the date archive hierarchy. From a user-interface perspective, date archives are normally implemented by linking on the publication date of a post. Clicking such a link will perform a query to retrieve all posts published on that date and display them on an archive page. The date link may be for a particular day, month, or year with the resulting query filtering the list of posts appropriately. As with other archives, the Loop takes care of the filtering and ordering (reverse-chronological by default) of the posts based on the link’s URL.

As with all of the archive types, the date archive will use the archive.php template in lieu of index.php if it resides in the theme directory. However, archive.php can be overridden with date.php if special formatting is needed for date archives. Although post filtering is available for different timeframes, there are not different templates available for each.

Assign Publication Dates

Let’s begin our exploration of the date archives by setting the publication dates of our existing posts to specific values. In this way, you will see the same results as I show in the examples and we’ll be able to scatter the dates around several different months. You can set the publication date using the Quick Edit function on the Posts→All Posts page of the Administration Screen. For each post, set the Date to the value from the table below (the time doesn’t matter). Be sure to click Update after changing each date.

Post Title Date
Post 1 December 12, 2012
Post 2 December 31, 2012
Post 3 January 14, 2013
Post 4 January 23, 2013
Post 5 February 3, 2013
Post 6 February 16, 2013
Post 7 March 14, 2013
Post 8 March 14, 2013
Post 9 March 30, 2013
Post 10 April 1, 2013
Book 1 April 1, 2013
Book 2 April 27, 2013
Book 3 May 14, 2013

After updating the publication dates, your Posts→All Posts page should look similar to the screenshot below.

Update publication dates

Updated publication date can be viewed on the All Posts page.

Display Publication Dates

Now that we have a variety of publication dates on our posts, let’s display them in the post list generated by our index.php template. For this demonstration, I’ll add the Pub Date column after the Author column in the table. There are several ways to do this. The method I chose uses two steps. In the first step I use calls to get_the_time() to return the publication date in three parts: year, month, and day. In the second step I pass those values to get_day_link() to generate the URL for the date archive. Here’s the revised code for index.php:

<?php
get_header(); 
echo "<p>In index.php</p>\n";

if (have_posts()) {   // if there are posts
	echo "<table>\n";
	echo "<tr><th>ID</th><th>Title</th><th>Format</th><th>Author</th>",
			"<th>Pub Date</th><th>Category</th><th>Tags</th></tr>\n";
	while (have_posts()) {   // start the loop
		the_post();
		echo "<tr>";
		echo "<td>", get_the_ID(), "</td>";
		echo "<td><a href='", get_permalink(), "'>",
				get_the_title(), "</a></td>";
		$postFormat = get_post_format();
		echo "<td>", $postFormat ? $postFormat : 'standard', "</td>";
		echo "<td>", the_author_posts_link(), "</td>";
		$year = get_the_time('Y');
		$month = get_the_time('m');
		$day = get_the_time('d');
		echo "<td><a href='", get_day_link($year, $month, $day), "'>",
			get_the_date(), "</a></td>";
		echo "<td>", get_the_category_list(', '), "</td>";
		echo "<td>", get_the_tag_list('', ', '), "</td>";
		echo "</tr>\n";
		}
	echo "</table>\n";
	next_posts_link("Older posts");
	echo "<br/>";
	previous_posts_link("Newer posts");
} else {
	echo "<p>no posts to display</p>\n";
}
    
get_sidebar();
get_footer();
?>

If you visit the site, you’ll see the page below.

Publication dates shown by index.php

The updated index.php template now shows the publication dates.

Clicking on the Older posts link displays the first three posts as shown below:

Page 2 of the post listing

Page 2 of the post listing.

Hover your mouse over the publication dates. Notice that the URLs are of the form http://localhost/lab1/year/month/day/. If you click on one of the links, say April 1, 2013, you will see the page below.

Daily archive

The archive.php template overrides index.php for this daily archive.

Notice that the archive.php template executes to fulfill the request for this date archive. The archive.php template is overriding index.php. To verify this, you can temporarily rename archive.php and refresh the page. The index.php file should be used instead. Next, let’s add the publication date to archive.php as we did for index.php earlier. Here’s the updated code:

<?php
get_header(); 
echo "<p>In archive.php</p>\n";

if (have_posts()) {   // if there are posts
	echo "<table>\n";
	echo "<tr><th>ID</th><th>Title</th><th>Format</th><th>Author</th>",
			"<th>Pub Date</th><th>Category</th><th>Tags</th></tr>\n";
	while (have_posts()) {   // start the loop
		the_post();
		echo "<tr>";
		echo "<td>", get_the_ID(), "</td>";
		echo "<td><a href='", get_permalink(), "'>",
				get_the_title(), "</a></td>";
		$postFormat = get_post_format();
		echo "<td>", $postFormat ? $postFormat : 'standard', "</td>";
		echo "<td>", the_author_posts_link(), "</td>";
		$year = get_the_time('Y');
		$month = get_the_time('m');
		$day = get_the_time('d');
		echo "<td><a href='", get_day_link($year, $month, $day), "'>",
			get_the_date(), "</a></td>";
		echo "<td>", get_the_category_list(', '), "</td>";
		echo "<td>", get_the_tag_list('', ', '), "</td>";
		echo "</tr>\n";
		}
	echo "</table>\n";
	next_posts_link("Older posts");
	echo "<br/>";
	previous_posts_link("Newer posts");
} else {
	echo "<p>no posts to display</p>\n";
}
    
get_sidebar();
get_footer();
?>

Refresh the date archive to ensure that the date was added correctly and note that both Post 10 and Book 1 have the selected publication date of April 1, 2013.

Exercise the Hierarchy

Next, let’s introduce a new template file, date.php. Copy archive.php to date.php. Change the trace message to In date.php and add another message to show the date of the archive. Also, now that we are displaying the date in a message, we can remove the redundant Pub Date column. Here’s the updated date.php code.

<?php
get_header(); 
echo "<p>In date.php</p>\n";
echo "<p>Browsing daily archive for ", get_the_time('F j, Y'), "</p>\n";

if (have_posts()) {   // if there are posts
	echo "<table>\n";
	echo "<tr><th>ID</th><th>Title</th><th>Format</th><th>Author</th>",
			"<th>Category</th><th>Tags</th></tr>\n";
	while (have_posts()) {   // start the loop
		the_post();
		echo "<tr>";
		echo "<td>", get_the_ID(), "</td>";
		echo "<td><a href='", get_permalink(), "'>",
				get_the_title(), "</a></td>";
		$postFormat = get_post_format();
		echo "<td>", $postFormat ? $postFormat : 'standard', "</td>";
		echo "<td>", the_author_posts_link(), "</td>";
		echo "<td>", get_the_category_list(', '), "</td>";
		echo "<td>", get_the_tag_list('', ', '), "</td>";
		echo "</tr>\n";
		}
	echo "</table>\n";
	next_posts_link("Older posts");
	echo "<br/>";
	previous_posts_link("Newer posts");
} else {
	echo "<p>no posts to display</p>\n";
}
    
get_sidebar();
get_footer();
?>

To get the date of the posts displayed on the archive page, I’m calling get_the_time(). This function takes a string parameter that determines the format of the date. This particular format string will display the full month name, the date, and the four-digit year. See the reference link for this function at the end of the article for more information on the date format string. If you now refresh the page, you will find that date.php overrides archive.php.

date.php overrides archive.php

The date.php template overrides archive.php.

That’s it for the date archive hierarchy. There is only one template, date.php, in the date archive hierarchy. The updated template hierarchy diagram is below.

Template Hierarchy with Date Archives

Like other archives, the date hierarchy begins with archive.php. There is a single level of this hierarchy represented by the date.php template. This template is used for all of the date timeframes: daily, monthly, and yearly.

Although having a link on the publish date to filter all posts published on a particular day might be useful on a very active blog, most sites have links for longer timeframes such as month and year. We’ll produce lists of publication months and years in our sidebar and footer, respectively. These links will allow us to further demonstrate the date archive mechanism and to customize the format of the resulting archive page by timeframe.

Add Monthly Archive Links to the Sidebar

Often you will see a list of monthly archive links in the sidebar on blog sites. Each of the links requests a date archive for a particular month. Let’s implement such a list in our sidebar.php template. Normally a list of monthly archive links would be generated by a widget, but we’ll just use the wp_get_archives() call to created an unordered list. The code is very simple as shown below. Here, we pass an array with a single name/value pair indicating to the function that we want a monthly archive.

<?php
echo "<p>In sidebar.php</p>\n";
echo "<ul>\n";
wp_list_categories();
echo "</ul>\n";

echo "<p>Monthly Archives</p>\n";
echo "<ul>\n";
wp_get_archives(array('type'=>'monthly'));
echo "</ul>\n";
?>

Navigating back to our home page, we can see the list of monthly archive links as shown in the next screenshot. If you hover over each link you will see that the generated URLs are of the form http://localhost/lab1/year/month/.

Monthly archive links are now shown in the sidebar

Monthly archive links are now shown in the sidebar.

If you click on one of the links, WordPress will issue a query for all posts published in the selected month. For example, clicking on April 2013 will cause the date.php template to produce the output shown below. Notice that the Loop has automatically queried the posts that were published in the selected month.

Monthly archive display

Clicking a monthly archive link causes date.php to display posts published during the selected month. We need to fix the message, however.

Since we coded date.php to produce a message for a daily archive, it is showing the full date for the first post on the list, Book 2. It would be preferable in this case for the message to indicate that we are viewing a monthly archive and to display only the month and year, instead. We’ll make a small change to date.php using the is_day(), is_month(), and is_year() conditional tags as shown below.

<?php
get_header(); 
echo "<p>In date.php</p>\n";
if (is_day())
	echo "<p>Browsing daily archive for ", get_the_time('F j, Y'), "</p>\n";
elseif (is_month())
	echo "<p>Browsing monthly archive for ", get_the_time('F Y'), "</p>\n";
else
	echo "<p>Browsing yearly archive for ", get_the_time('Y'), "</p>\n";

if (have_posts()) {   // if there are posts
	echo "<table>\n";
	echo "<tr><th>ID</th><th>Title</th><th>Format</th><th>Author</th>",
			"<th>Category</th><th>Tags</th></tr>\n";
	while (have_posts()) {   // start the loop
		the_post();
		echo "<tr>";
		echo "<td>", get_the_ID(), "</td>";
		echo "<td><a href='", get_permalink(), "'>",
				get_the_title(), "</a></td>";
		$postFormat = get_post_format();
		echo "<td>", $postFormat ? $postFormat : 'standard', "</td>";
		echo "<td>", the_author_posts_link(), "</td>";
		echo "<td>", get_the_category_list(', '), "</td>";
		echo "<td>", get_the_tag_list('', ', '), "</td>";
		echo "</tr>\n";
		}
	echo "</table>\n";
	next_posts_link("Older posts");
	echo "<br/>";
	previous_posts_link("Newer posts");
} else {
	echo "<p>no posts to display</p>\n";
}
    
get_sidebar();
get_footer();
?>

This code will test whether we are currently viewing a daily, monthly, or yearly archive and adjust the trace message accordingly. In each case, we change the message and pass a different date format string to get_the_time(). If you refresh the monthly archive page now, you should see the proper message for the monthly archive as shown below.

Fixed trace message for monthly archives

With a few conditional tags we straighten out the trace message display.

If you instead select one of the publish date links from the post list, you will see the daily archive message as before.

Add Yearly Archive Links to the Footer

Let’s also add a yearly archive list to the footer.php template. We will use the same call, wp_get_archives(), as we did for the monthly archives, except we’ll pass it a parameter to indicate that we want yearly archive links. Here is the revised code for footer.php:

<?php
echo "<p>In footer.php</p>\n";
wp_tag_cloud();
echo "<p>Authors:</p><ul>", wp_list_authors(), "</ul>";

echo "<p>Yearly Archives:</p>\n";
echo "<ul>\n";
wp_get_archives(array('type'=>'yearly'));
echo "</ul>\n";

echo "</body>\n";
echo "</html>\n";
?>

Navigating back to the home page, we see the yearly archive links in the footer. Hover over each link and note that the generated URLs are of the form http://localhost/lab1/year/.

Yearly archive links

Yearly archive links are now displayed in the footer.

If you click on one of the links, say 2012, you will see the date.php page display showing all posts published in 2012. Note that the trace message now correctly displays the yearly archive message.

Yearly archive display

Clicking a yearly archive link displays all posts published in the selected year.

In this article we examined the date archive hierarchy. It is rooted with the archive.php template file (as are all of the archives), but you can achieve special formatting of date archives by using the date.php template. Although there are no template files to differentiate between daily, monthly, and yearly archives, you can use the conditional tags is_day(), is_month(), and is_year() to conditionally format the different timeframes.

In the next article, we will continue along the archive hierarchy by looking at custom taxonomy archives. In the process, we’ll create a custom taxonomy to use for testing and assign terms of that taxonomy to our posts.

References

Speak Your Mind

*