I was recently asked how I built the sitemap on Binary Moon so I thought I would share the code. The sitemap layout is actually one of the many custom page templates available in my WordPress theme, Elemental – however the code is very loosly based upon that in the original SRG Clean Archives plugin (before it was taken over by Geek With a Laptop).
Sitemaps are a single page that allows you to view every single post on a site. Perfect for Google to spider all of your content, and for users to quickly find old posts that they are looking for.
When making the sitemap I wanted to list all of the posts, and also to link to the monthly archives for each post – that way I would get maximum exposure for my sitemap – and it has a page rank of 6 (at the time of writing) so I must be doing something right.
The process is relatively simple:
- Grab all the months and years from the database
- Loop through the list of dates and grab the posts from each month, displaying them as you go
Easy right? The code, that you would add to your functions.php – would look something like the function below:
function bm_displayArchives() {
global $month, $wpdb, $wp_version;
// a mysql query to get the list of distinct years and months that posts have been created
$sql = 'SELECT
DISTINCT YEAR(post_date) AS year,
MONTH(post_date) AS month,
count(ID) as posts
FROM ' . $wpdb->posts . '
WHERE post_status="publish"
AND post_type="post"
AND post_password=""
GROUP BY YEAR(post_date),
MONTH(post_date)
ORDER BY post_date DESC';
// use get_results to do a query directly on the database
$archiveSummary = $wpdb->get_results($sql);
// if there are any posts
if ($archiveSummary) {
// loop through the posts
foreach ($archiveSummary as $date) {
// reset the query variable
unset ($bmWp);
// create a new query variable for the current month and year combination
$bmWp = new WP_Query('year=' . $date->year . '&monthnum=' . zeroise($date->month, 2) . '&posts_per_page=-1');
// if there are any posts for that month display them
if ($bmWp->have_posts()) {
// display the archives heading
$url = get_month_link($date->year, $date->month);
$text = $month[zeroise($date->month, 2)] . ' ' . $date->year;
echo get_archives_link($url, $text, '', '<h3>', '</h3>');
echo '<ul class="postspermonth">';
// display an unordered list of posts for the current month
while ($bmWp->have_posts()) {
$bmWp->the_post();
echo '<li><a href="' . get_permalink($bmWp->post) . '" title="' . wp_specialchars($text, 1) . '">' . wptexturize($bmWp->post->post_title) . '</a></li>';
}
echo '</ul>';
}
}
}
}
Note that I am using the wp_query object (as detailed in my post “10 query_posts tips you probably don’t know“) throughout this example to stop the main query_posts instance from being ruined
To use the function above you would then need to create a custom page template (as detailed in the custom page template tutorial here). You can then call the function from within the new template.
Was it good/ useful/ a load of old rubbish? Let me know on Mastodon, or BlueSky (or Twitter X if you must).
Link to this page
Thanks for reading. I'd really appreciate it if you'd link to this page if you mention it in your newsletter or on your blog.