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:
- Create a template file in my theme folder, for instance,
all-my-posts-so-far.php
- 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:
- Database access codes that retrieve all the published posts in my blog.
- Iteration codes that display the post.
- 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:
- Check if posts from the latest month had been visited, if yes, print a HTML unordered list end tag; if no, set
$latestMonthVisited
toTRUE
. - 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.