the graphic design blog that speaks the truth

This post will describe the easy method of nesting your wordpress archives in a dropdown list using jQuery and some simple CSS.

The default function

The default options that WordPress offers in displaying your blogs archives are rather rigid, in that you can only display them in one way. Using the wordpress wp_get_archives function we can set the following options:

<?php wp_get_archives('type=daily'); ?>

To display a list of archives grouped by date.

<?php wp_get_archives('type=weekly'); ?>

To display a list of archives grouped by week.

<?php wp_get_archives('type=monthly'); ?>

To display a list of archives grouped by month.

<?php wp_get_archives('type=yearly'); ?>

To display a list of archives grouped by year.

All are very handy functions to use. Depending on the amount of blog posts you have, you use the necessary function. I.e, if you had 2000 posts on your blog, you are unlikely to choose the daily option as it would take up a huge amount of space on your site. This is not a foolproof solution though. What if you wanted to display a list of archives grouped by year, and then display the corresponding months in a handy dropdown menu?

Extending the function

The following simple code snippet will set up an archive list grouped by year, and place any child months of each year in a sub menu:

<div class="blog-list-archive">

<?php
/**/
$years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date)
FROM $wpdb->posts WHERE post_status = 'publish'
AND post_type = 'post' ORDER BY post_date DESC");
foreach($years as $year) :
?>
<li><a href="JavaScript:void()"><?php echo $year; ?></a>

    <ul class="archive-sub-menu">
        <?    $months = $wpdb->get_col("SELECT DISTINCT MONTH(post_date)
        FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post'
        AND YEAR(post_date) = '".$year."' ORDER BY post_date DESC");
        foreach($months as $month) :
        ?>
            <li><a href="<?php echo get_month_link($year, $month); ?>">

                <?php echo date( 'F', mktime(0, 0, 0, $month) );?></a>

            </li>

        <?php endforeach;?>

    </ul>

</li>

<?php endforeach; ?>

</div>

As you can see, the code does exactly what you would expect. It selects a yearly archive from your WordPress database, and then selects the child months of said year and places them in a sub menu named ‘archive-sub-menu’, looping through for every year your blog archive contains. Don’t worry about the div named ‘blog-list-archive’, this is simply added so we can reference a container in the jQuery code later on. We now have a unordered list of archives (both yearly and monthly) that we can turn into a dropdown list.

Creating the dropdown

Firstly, we need to hide the sub menus, so that they only display when the yearly titles are clicked.

.archive-sub-menu {

display:none;

}

achieves this. Next, we simply add a very simple snippet of jQuery code that will display each years corresponding monthly drop-down archive when clicked.

<script type="text/javascript">

$(document).ready(function() {

    $('.blog-list-archive li ul').hide();
    $('.blog-list-archive li a').click(function(){
        $(this).parent().addClass('selected');
        $(this).parent().children('ul').slideDown(250);
        $(this).parent().siblings().children('ul').slideUp(250);
        $(this).parent().siblings().removeClass('selected');
    });
});

</script>

NOTE: The lines ‘$(this).parent().addClass(‘selected’);’ and ‘$(this).parent().siblings().removeClass(‘selected’);’ simply enable you to style the title of the currently selected archive.

That’s all there is to it! Please feel free to download the full code.

ABOUT THE AUTHOR

SHARE THIS ARTICLE

  1. 29/03/12
    11:02 am
    I was just looking for something like this I'll give it a go. Thanks for sharing ;-)
  2. 05/07/12
    5:29 am
    i like it ... its usfull.. nice job.
  3. 27/11/12
    4:52 pm
    Great piece of code, exactly what I was after. Can you show me a way to skip a single month in the archive list?
  4. 14/12/12
    11:19 am
    Hi Trix, glad you found it useful. To remove a month from the list, just add an if statement before you start echoing out the months: <?php if (date( 'F', mktime(0, 0, 0, $month) ) != 'March') { ?> <li><a href="< echo get_month_link($year, $month); ?>"> <?php echo date( 'F', mktime(0, 0, 0, $month) );?></a> </li> <?php } ?> Hope that helps :)
  5. 26/01/13
    12:01 pm
    This is very useful but I cannot get months in Italian. WP config, locale file and all other settings are already set in Italian. Any idea? Thanks in advance.
  6. 14/02/13
    4:23 pm
    Awesome. Helped me out big time! Cheers. Quick question, though - How would i go about adding the post count to each month? e.g. January (2)
  7. 21/05/13
    6:47 pm
    YOU DA MAN!
  8. 09/08/14
    5:30 am
    Very Nice Thanks :)
  9. 12/08/14
    8:51 am
    Reg
    Sorry for being dumb, but...where does this code go?
  10. 23/12/14
    11:36 pm
    if you change: $(this).parent().children('ul').slideDown(250); to: $(this).parent().children('ul').slideToggle(250); It will close the current year if you click on it again.
  11. 05/03/15
    5:22 pm
    Hi, Great code, although your code creates an error warning in debug. to correct this in the html code change to
  12. 09/07/15
    6:08 am
    nice one
  13. 03/12/16
    7:53 pm
    Hi Daniel, just want to share a small improvement with you. One thing about this code is that you're running a MySQL Query for each month in your list. In the developer community that's known as the n+1 problem. It means the more entries you have the more DB queries are being made, making your site slower as it grows (or months pass by). I suggest one db query grabbing you year and months in one, then restructuring it after getting it using WordPress' $wpdb->get_results function with the ARRAY_A mode. I would post a code example here but I can't because of security restrictions.
Voice Your Opinion

Thanks for your comment, it will appear here once it has been moderated.