How to show year/month archive including months with no posts

I found a partial answer at: http://floatleft.com/notebook/wordpress-year-month-archives/

This solution shows all months that have posts. Its not even that much code:

Read More
<?php
        $year_prev = null;
        $months = $wpdb->get_results(   "SELECT DISTINCT MONTH( post_date ) AS month ,
                                        YEAR( post_date ) AS year,
                                        COUNT( id ) as post_count FROM $wpdb->posts
                                        WHERE post_status = 'publish' and post_date <= now( )
                                        and post_type = 'post'
                                        GROUP BY month , year
                                        ORDER BY post_date DESC");
        foreach($months as $month) :
            $year_current = $month->year;
            if ($year_current != $year_prev){
                if ($year_prev != null){?>
                </ul>
                <?php } ?>
            <h3><?php echo $month->year; ?></h3>
            <ul class="archive-list">
            <?php } ?>
            <li>
                <a href="<?php bloginfo('url') ?>/<?php echo $month->year; ?>/<?php echo date("m", mktime(0, 0, 0, $month->month, 1, $month->year)) ?>">
                    <span class="archive-month"><?php echo date("F", mktime(0, 0, 0, $month->month, 1, $month->year)) ?></span>
                </a>
            </li>
        <?php $year_prev = $year_current;
        endforeach; ?>
        </ul>

My problem is that the designer added all the months, not just the ones that have posts. How could I edit this to show all months, not just the ones with posts. I am using 3.8.1

thanks

Related posts

2 comments

  1. The code below will loop through everywhere year and check to see if each month has posts. If so, it will add a link to the month. If not, it will just print the month without a link. You will need to edit the actual link as I am not sure about your websites’ permalink structure.

    //Grab the earliest year available
        $yearliest_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
    
        ");
    
    
        //If there are any posts
        if($yearliest_year){
    
            //This year
            $this_year = date('Y');
    
            //Setup months
            $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");
    
            $current_year = $yearliest_year[0]->year;
    
    
            //Loop through every year and check each monnth of each year for posts
            while($current_year <= $this_year){
    
                echo "<h3>" . $current_year . "</h3>";
    
                echo "<ul>";
    
                foreach($months as $month_num => $month){
    
    
                    //Checks to see if a month a has posts
                    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 
    
                    ")){
    
                        //Month has post -> link it
                        echo "<li>
    
                                <a href='" . get_bloginfo('url') . "/" . $current_year . "/" . $month_num . "/'><span class='archive-month'>" . $month . "</span></a>
    
                              </li>";
    
    
                    }else{
    
                        //Month does not have post -> just print it
    
                        echo "<li>
    
                                <span class='archive-month'>" . $month . "</span>
    
                              </li>";
                    }
    
    
    
                }
    
                echo "</ul>";
    
                $current_year++;
    
    
            }
    
        }else{
    
            echo "No Posts Found.";
    
        }
    
  2. One solution would be to add the missing months. You have check if all the months of a existent year is present. If not, you add that month with post_count zero.

    <?php
            $year_prev = null;
            $months = $wpdb->get_results(   "SELECT DISTINCT MONTH( post_date ) AS month ,
                                            YEAR( post_date ) AS year,
                                            COUNT( id ) as post_count FROM $wpdb->posts
                                            WHERE post_status = 'publish' and post_date <= now( )
                                            and post_type = 'post'
                                            GROUP BY month , year
                                            ORDER BY post_date DESC");
    
            function month_exist($month, $year, $objects){
                foreach($objects as $object){
                    if( ($object->month == $month) && ($object->year == $year) )
                    return true;
                }
                return false;
            }
    
            $all_month = range(1,12);
            $new_array = $months;
            $i = 0;
            foreach($months as $month){
                $year_current = $month->year;
                if( $year_current != $year_prev ){
                    foreach( $all_month as $current_month ){
                        if( !month_exist($current_month, $month->year, $months)){
                            $value = new StdClass();
                            $value->month = $current_month;
                            $value->year = $month->year;
                            $value->post_count = 0;
                            array_splice($new_array, $i*12+($current_month-1), 0, array($value));
                        }
                    }
                    $i++;
                }
                $year_prev = $month->year;
            }
    
            $months = $new_array;
            $year_prev = null;
            foreach($months as $month) :
                $year_current = $month->year;
                if ($year_current != $year_prev){
                    if ($year_prev != null){?>
                    </ul>
                    <?php } ?>
                <h3><?php echo $month->year; ?></h3>
                <ul class="archive-list">
                <?php } ?>
                <li>
                    <a href="<?php bloginfo('url') ?>/<?php echo $month->year; ?>/<?php echo date("m", mktime(0, 0, 0, $month->month, 1, $month->year)) ?>">
                        <span class="archive-month"><?php echo date("F", mktime(0, 0, 0, $month->month, 1, $month->year)) ?></span>
                    </a>
                </li>
            <?php $year_prev = $year_current;
            endforeach; ?>
            </ul>
    

Comments are closed.