Are you looking for a way to display a beautifully formatted archives list of months separated by year? While there’s probably a plugin for this, we have created a quick code snippet that you can use to display formatted archives by month separated by year in WordPress.
Instructions:
All you have to do is add this code to your theme’s functions.php file or in a site-specific plugin:
function wp_custom_archive($args = '') { global $wpdb, $wp_locale; $defaults = array( 'limit' => '', 'format' => 'html', 'before' => '', 'after' => '', 'show_post_count' => false, 'echo' => 1 ); $r = wp_parse_args( $args, $defaults ); extract( $r, EXTR_SKIP ); if ( '' != $limit ) { $limit = absint($limit); $limit = ' LIMIT '.$limit; } // over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride $archive_date_format_over_ride = 0; // options for daily archive (only if you over-ride the general date format) $archive_day_date_format = 'Y/m/d'; // options for weekly archive (only if you over-ride the general date format) $archive_week_start_date_format = 'Y/m/d'; $archive_week_end_date_format = 'Y/m/d'; if ( !$archive_date_format_over_ride ) { $archive_day_date_format = get_option('date_format'); $archive_week_start_date_format = get_option('date_format'); $archive_week_end_date_format = get_option('date_format'); } //filters $where = apply_filters('customarchives_where', "WHERE post_type = 'post' AND post_status = 'publish'", $r ); $join = apply_filters('customarchives_join', "", $r); $output = '<ul>'; $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC $limit"; $key = md5($query); $cache = wp_cache_get( 'wp_custom_archive' , 'general'); if ( !isset( $cache[ $key ] ) ) { $arcresults = $wpdb->get_results($query); $cache[ $key ] = $arcresults; wp_cache_set( 'wp_custom_archive', $cache, 'general' ); } else { $arcresults = $cache[ $key ]; } if ( $arcresults ) { $afterafter = $after; foreach ( (array) $arcresults as $arcresult ) { $url = get_month_link( $arcresult->year, $arcresult->month ); /* translators: 1: month name, 2: 4-digit year */ $text = sprintf(__('%s'), $wp_locale->get_month($arcresult->month)); $year_text = sprintf('<li>%d</li>', $arcresult->year); if ( $show_post_count ) $after = ' ('.$arcresult->posts.')' . $afterafter; $output .= ( $arcresult->year != $temp_year ) ? $year_text : ''; $output .= get_archives_link($url, $text, $format, $before, $after); $temp_year = $arcresult->year; } } $output .= '</ul>'; if ( $echo ) echo $output; else return $output; }
Add this snippet in your index.php file or any other template file where you want to display the formatted archives.
<?php wp_custom_archive(); ?>
Note: If this is your first time adding code snippets in WordPress, then please refer to our guide on how to properly copy / paste code snippets in WordPress, so you don’t accidentally break your site.
If you liked this code snippet, please consider checking out our other articles on the site like: 9 best WordPress auction plugins and how to create a guest post submission form in WordPress.
Great work Dear..
can you please tell me how to show post count by months?
right now it showing the month names
How to remove recent month of the year in this plugins?
$temp_year not defined 😉
Awesome code! Thanks a lot man!
No problem glad I could help!
Awesome code! Thanks a lot man!
Awesome code! Thanks a lot man!
Awesome code. Exactly what I was looking for. Do you, perhaps know how to refine it to only pull in a custom post type? *waiting hopefully 🙂
post_type is defined here, “WHERE post_type = ‘post'”
This is a very good example. Thanks, Now, it’s possible loading months of a specify category?
Very bealtifully. Great. Thanks!
Wow. That’s a great solution without a plugin. Works perfekt. Thanks for the snippet
Exactly what i needed, this should be baked into wordpress core it’s so good
Great solution, thanks 🙂
Dear Kevin,
Hard to understand your script. Would you like to attach it with tabel in database MySql? May be it more clearly for me because I am new in PHP. Thanks
I know this is an old post. But is there any way to specify the category of the archive list? Preferably by passing the value from the wp_custom_archive tag. So that I could put several archive lists on a page. i want an archive list for category 9 and a separate archive list for category 4. So that the tag would be something like wp_custom_archive(‘9’) and wp_custom_archive(‘4’).
Any help?
hhhmmm Hi John, many archive plugins exist that might be a better solution when wanting to get this detailed with your archives.
If you’re still wondering, I’ve posted modified code above (5/29/2017) that allows for filtering by category.