WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Alright, I was starting on the code for my blog today when I ran into a little issue. However, before I ask my question, it my help if I actually explain what the functionality I am hoping to achieve. (you can also view my header comp at http://louisstephens.cc/comps/blog.png )

In my header, I am going to have the year with all the months listed under it. The current month will be selected showing all the posts for that month. However, the other months will also be selectable, and doing so will fade out the current month's post to show the newly selected month's posts (as well as changing the "active" state of the selected month). When a new year comes around, you can simply click on a side arrow (that will be next to the year), and it will slide the header over to that year and month set).

Maybe this can't be done, but I was having an issue. For the life of me, I can not figure out how to show all the months regardless of them containing any posts. I know I can use:

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

But if no posts are present, no months show up. Has anyone ever figured out a way around this, or have any clue of what can be done to achieve my desired effect?

share|improve this question
Why not just let it build as the months pass? I think that would look really good actually, and probably minimize confusion – mor7ifer Jan 22 '12 at 18:18
I agree, but if you need to do this see my answer. – Jared Jan 22 '12 at 20:13

How about making an array of months and then getting the posts per-month? Though I suspect this is somewhat less efficient than @Jared's...

function get_posts_grouped_by_month( $year = null ) {

    if ( $year == null ) {
        $year = date('Y');

    $months = range(1,12);
    $posts = array();

    foreach ( $months as $month ) {
        $posts_for_month = get_posts(array(
            'year' => $year,
            'monthnum' => $month ));
        $posts[$month] = $posts_for_month;

    return $posts;

then, in the template:

<?php $monthly_posts = get_posts_grouped_by_month(2011); ?>

<?php foreach ( $monthly_posts as $month => $posts ) { 
    echo "<ul><strong>" . $month . "</strong>\n";   
    foreach ( $posts as $post ) {
        echo "<li>" . get_permalink($post->ID) . "</li>";
    echo "</ul>";
} ?>
share|improve this answer

If you insist on showing all months, what I would do is use wp_get_archives to return the string in a custom format and then use PHP DOMDocument to parse it, creating an array of months and adding those that don't exist yet.

I think it would be a bit more complex than you may hope for but here's a really basic example:

$archives = wp_get_archives( array(
    'type' => 'monthly',
    'echo' => 0,
    'format' => 'custom',
    'before' => '',
    'after' => ''
) );

$dom = new DOMDocument();
@$dom->loadHTML( "<?xml encoding='" . get_bloginfo( 'charset' ) . "'>" . $archives );

$xpath = new DOMXPath( $dom );
$months = $xpath->query( '//a' );

$months_array = array();
foreach( $months as $month ) {

    $name_year = $month->nodeValue;
    $link = $month->getAttribute( 'href' );
    $months_array[] = array( 'title' => $name_year, 'url' => $link );


unset( $xpath, $dom ); // Clean up

// Do something to add the months that don't exist to $months_array
// Possibly give them the '#' or 'javascript:;' URL?

// Echo accordingly
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.