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.
How was it for you? Let me know on BlueSky or Mastodon
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.