Making monthly archive dropdown lists in WordPress

30 July 2005

I was asked by Armand how to do the month-by-month blog archive drop-down in the right hand column of the blog, which, if you have archives going back some time, saves having an enormous list of months (which, IMHO, looks ugly). WordPress’s get_archives() function does provide drop-down capability, but only by using JavaScript to handle the form submission, which is just dumb, and breaks badly if you don’t have JavaScript enabled.

So, I wrote a hack that does the drop-down, but handles it using standard HTTP form submission (which is nice). There is a bit of JavaScript, an event handler to submit the form straight away when a selection is made, but this is a convenience thing, and it still works the old-fashioned way if you have JavaScript disabled.

Here goes… first of all it’s just a hack, not a plugin, so you’ll need to have a my-hacks.php file set up and running – see here for more details.

Once you have my-hacks.php open, add the following inside the PHP code:

function make_month_dropdown() {
	global $wpdb, $tableposts, $month;
	$now = current_time('mysql');
	// Get the entries grouped by month and year
	$archiveEntries =
		$wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS `year`,
		MONTH(post_date) AS `month`
		FROM $tableposts WHERE post_date < '$now' AND post_status = 'publish'
		GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC");
	// Start form
	echo '<form action="'.get_settings('home').'/" method="get">';
	echo '<div><select name="m" class="small" onchange="this.form.submit();">';
	// Produce each line of the dropdown
	foreach($archiveEntries as $archiveEntry) {
		// Add leading zero
		$thisMonth = zeroise($archiveEntry->month,2);
		// value to be passed into query string
		$thisM = $archiveEntry->year.$thisMonth;
		echo "<option value=\"$thisM\"";
		// Preselect currently-viewed month
		if ($thisM == $_GET['m']) echo ' selected="selected" ';
		echo '>';
		echo $month[$thisMonth].' '.$archiveEntry->year;
		echo '</option>';
	}
	echo '</select>&nbsp;';
	echo '<input type="submit" value="&raquo;" />';
	echo '</div></form>';
}

Save that (and upload). Then in your template file (sidebar.php), replace the line beneath the archive header, that says <?php get_archives(); ?> (or something similar) with:

<?php make_month_dropdown(); ?>

And you should be done. Hopefully. Feedback in the comments below.


7 Responses

Works well, many thanks. As you’ll see from my blog, the “go” button doesn’t look good… trying to work out how to get rid of it, wisdom appreciated…

Thanks for posting this: it was just what I was looking for. I’d rather the Go button was on the same line as the drop-down list, but I assume that’s a function of my relatively narrow sidebar not having room for both.

John, I was wondering why your RSS feed had dried up – didn’t know you’d switched over and was still using the old URL! Anyway, yes, the sidebar often doesn’t accomodate it very well – I had to shrink the drop-down and make the button as tiny as possible to work on mine. Dispensing with the button altogether may make it look nicer, though it will break the form for anyone without JS…

Hi, i am brazilian blogger, and i just installed the hack, congratullations, its wonderfull.
Why not create an dropdown list for Categories too?
Thanks a lot!

Unfortunately my switch to WordPress was forced on me by a corrupted Movable Type database, and in the rush to get WP up and running I put “sort out a transition from old to new RSS feed addresses” on my to-do list but somehow never actually got round to doing anything about it. Now that you’ve reminded me of my (very embarrassing!) omission I’ll have to get that sorted out.

I’ve no intention of ditching the Go button on the archives drop-down; I can certainly live with the current arrangement. Let’s face it, I wouldn’t blame anyone for browsing with Javascript turned off nowadays – especially if they’re using a browser without any popup handlers – so I’ll do my best to keep the site usable even if it isn’t quite as pretty. (In any case the next time I feel the need to switch layouts I may just end up with a wider sidebar. Come to think of it, if I ever put by blogroll back up – yet another task that got lost in the shuffle during the MT-WP transition – I’m definitely going to need a wider sidebar anyway.)

Anyway, I’m glad my comment has brought my continued existence to your attention.

One thought – some skin designers, annoyed at having too narrow a space for the search box, have put it at the foot or head of the page, and are no longer restricted by the column – maybe this isn’t intuitive enough a place for many users, though.

Actually, that sounds like a decent idea. If your design has room for a distinctive “menu bar” between your page’s title and your main content, perhaps using a contrasting background colour, that would seem to be a natural place for a search box and maybe also drop-down lists of archives by month and category. You could think of it as a filter for the entries that follow.

Something to consider next time I’m playing with a new design…

[Incidentally, following your comment above I've now set up a permanent redirect of my old RSS feeds' addresses to point at the new feeds, so any other old readers who haven't deleted my feed from their aggregator are about to find out that I'm still around. Thanks again for reminding me of my omission.]