1

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:

<?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

2 Answers 2

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.";

    }
0
0

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>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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