How I create a page in my WordPress blog that lists all my posts and groups them by month and year

I realised that there was something missing in my WordPress blog; a page that lists all the posts that I had written so far. This post documents what I had explored to give my blog a page that lists all my posts, starting from the most recent post down to the oldest post, and groups them by month and year.

A high level plan

I first did some research on this topic. In order to include a page that list all the posts in my WordPress blog, I will need to do the following:

  1. Create a template file in my theme folder, for instance, all-my-posts-so-far.php
  2. Create a page and name it as "All Posts" and set the template file as all-my-posts-so-far.php.

The parts that form all-my-posts-so-far.php

I broke down the codes in all-my-posts-so-far.php into the following parts:

  1. Database access codes that retrieve all the published posts in my blog.
  2. Iteration codes that display the post.
  3. Conditional codes that group posts of the same month and year together.

The database access codes that retrieve all the published posts in my blog

global $wpdb;
$allPostsArray = $wpdb->get_results(
	'SELECT ID, post_title, post_date, post_name FROM ' . 
         $wpdb->posts . 
        ' WHERE post_type=\'post\' AND post_status = \'publish\'' .
        ' ORDER BY post_date desc'
);

I globalize the $wpdb variable to gain code access to my WordPress database. I then call its get_results function, passing it a SQL select statement to get all my posts. The SQL statement looks for posts with the post_type column having a "post" value, the post_status column having a "publish" value, ordered by the post_date column in descending order.

The $wpdb->posts variable is used to retrieve the actual name of the table in my WordPress database that stores all my posts.

Iteration codes that display the posts and conditional codes that group posts of the same month and year together

$earlierPostMonthYear = 'January 2000';	
$latestMonthVisited = FALSE;
foreach($allPostsArray as $post) {
    
    $postDate = date_create($post->post_date);
    $currentPostMonthYear = date_format($postDate, 'F Y');
		
    $postFromAnotherMonthYear = ($currentPostMonthYear != $earlierPostMonthYear);
	
    if ($postFromAnotherMonthYear) {

        if (!$latestMonthVisited) {
	    $latestMonthVisited = TRUE;
	}
	else {
	    echo '</ul>';
	}
?>
<h3><?php echo $currentPostMonthYear?></h3>
<ul>
<?php
	} // end if ($postFromAnotherMonthYear)	
?>
<li>
	<a href="<?php echo get_bloginfo('url') . '/' . $post->post_name;?>" 
           title="<?php echo $post->post_title;?>">
	<?php echo $post->post_title;?>
	</a>
</li>
<?php
	$earlierPostMonthYear = $currentPostMonthYear;
    } // foreach
?>

I place the $allPostsArray variable in a foreach loop, setting each post record into the $post variable. I then use the date_create and date_format functions to get a string representation of the month and year of the current post.

I then compare the month and year of the current post with the month and year of the previous post. When there is a difference, I do the following:

  1. Check if posts from the latest month had been visited, if yes, print a HTML unordered list end tag; if no, set $latestMonthVisited to TRUE.
  2. Print out the HTML unordered list start tag along side a HTML header level 3 element that enclosed the month and year of the current post.

Outside the check, I print a HTML list element that enclosed the HTML link to the current post.

Create a WordPress page, name it as "All Posts", and link it to all-my-posts-so-far.php

Well the final step is straightforward. I hover to the "Pages" menu item at the left of my WordPress administrator site and click on the "Add New" link.

I typed in "All posts" in the first text field, and the locate the Template dropdown at the "Page Attributes" section at the right. But wait...

Where is the option value for my all-my-posts-so-far.php WordPress template at the "Page Attributes" section?

It turned out that I had left something out at the start all-my-posts-so-far.php.

To be able to select all-my-posts-so-far.php as the template file to link to the "All posts" page, I had to place the following code at the start of the file:

/*
Template Name: All my posts so far
*/

With that, I completed the inclusion of a page that lists all the posts in my WordPress blog and groups them by month and year.

About Clivant

Clivant a.k.a Chai Heng enjoys composing software and building systems to serve people. He owns techcoil.com and hopes that whatever he had written and built so far had benefited people. All views expressed belongs to him and are not representative of the company that he works/worked for.