Compact archives in WordPress without a plugin

If you’ve been blogging for any length of time, you might have an archive index page that lists your posts by month or year for easy viewing. And if you’ve been blogging for a long time, that list might be rather long like mine was.

And there are whole months that I skipped
And there are whole months that I skipped

Instead of such a lengthy list, what if you had something more compact? Where each year was a single line and all of the months, whether you posted in them or not, were listed horizontally.

Only 6 lines now

There are plugins you can install that do all the work for you, but some plugins don’t get updated and they’re not as customizable as you want them to be. There’s also surprisingly little code needed for compact archives so a plugin might be overdoing it.

The first step is to list out all the years and months. You can do that by placing the following code in the functions.php file of your theme (based of a Stackexchange question):

 //Compact archives for the archive index page
function custom_archives() {
    global $wpdb;
    $earliest_year = $wpdb->get_results("SELECT YEAR(post_date) AS year FROM ".$wpdb->posts." WHERE post_status = 'publish' AND post_type = 'post' ORDER BY post_date ASC LIMIT 1");
    $latest_year = $wpdb->get_results("SELECT YEAR(post_date) AS year FROM ".$wpdb->posts." WHERE post_status = 'publish' AND post_type = 'post' ORDER BY post_date DESC LIMIT 1");

    if($earliest_year){
        $oldest_year = $earliest_year[0]->year;
        $months = array(1 => "January", 2 => "February", 3 => "March" , 4 => "April", 5 => "May", 6 => "June", 7 => "July", 8 => "August", 9 => "September", 10 => "October", 11 => "November", 12 => "December");
        $newest_year = $latest_year[0]->year;
        $current_year = $newest_year;
        echo "<ul>";

        while($current_year >= $oldest_year){
            echo "<li><span class='year'>".$current_year."</span><ul>";

            foreach($months as $month_num => $month){
                if($search_month = $wpdb->query("SELECT MONTHNAME(post_date) as month FROM ".$wpdb->posts." WHERE MONTHNAME(post_date) = '".$month."' AND YEAR(post_date) = ".$current_year." AND post_type = 'post' AND post_status = 'publish' LIMIT 1")){
                    echo "<li><a href='".get_bloginfo('url')."/".$current_year."/".$month_num."/'>".substr($month, 0, 3)."</a></li>";
                } else {
                    echo "<li>".substr($month, 0, 3)."</li>";
                }
            }
            echo "</ul></li>";
            $current_year--;
        }
        echo "</ul>";
    } else {
    echo "No Posts Found.";
    }
}

Then on your archive page template (archive.php), add:

<div id="compact-archive"><?php if (function_exists('custom_archives')) { custom_archives(); } else { wp_get_archives('type=monthly'); } ?></div>

The wp_get_archives() is a fallback in case something goes wrong.

At first glance, you’ll see that it outputs a long list of years and months, not the compact archive I promised. But I assure you, there is a method to my madness. I made it show the archives in lists because it can be manipulated with CSS easily and I believe it’s more schematically correct.

To get the compact style, add the following to the style.css of your theme:

#compact-archive ul { margin:0; padding:0; list-style-type:none; }
#compact-archive ul, #compact-archive li { display:inline-block; }
#compact-archive .year { font-weight:bold; }
#compact-archive .year:after { content:": "; }
#compact-archive ul ul li { width:2.7em; text-align:center; }
#compact-archive ul ul li a { font-weight:bold; }

And the result should appear similar to the screenshot I have above.

It can also be styled with vertical bars separating the months.

#compact-archive ul { margin:0; padding:0; list-style-type:none; }
#compact-archive ul, #compact-archive li { display:inline-block; }
#compact-archive .year { font-weight:bold; }
#compact-archive .year:after { content:": "; }
#compact-archive ul ul li:before { content:" |"; color:#6b6b6b; }
#compact-archive ul ul li:first-child:before { content:""; }
Compact archives with separator

Those are just two examples of how you could style it. It will look better if you make a post at least once a month, unlike the lazy blogger I am.

If you have any questions or ideas on how to improve this code, please post a comment below!

September 10, 2014 No comments /

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.