0

I need to show all months for a year for an archives page. All 12 months must be shown regardless of whether or not there are posts published for a month. Like this:

Year: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

Of course, months with published posts are links. Months with no published posts are simply the word

This is my code:

<ul>

<?php
    global $wpdb;
    $limit = 0;
    $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){ ?>

    <?php } ?>

    <li> <a class="year" href="<?php bloginfo('url') ?>/<?php echo $month->year; ?>/">> <?php echo $month->year; ?></a>

    <?php } ?>

    <a class="month" href="<?php bloginfo('url') ?>/<?php echo $month->year; ?>/<?php echo date("m", mktime(0, 0, 0, $month->month, 1, $month->year)) ?>"><?php echo date_i18n("M", mktime(0, 0, 0, $month->month, 1, $month->year)) ?></a>

    <?php $year_prev = $year_current; if(++$limit >= 10) { break; } endforeach; ?></li>
</ul>

I achieved what I pretend to do except for showing all the 12 months.

2
  • This is the same kind of problem as here though that one deals with years and not months. Take a look. See if it helps.
    – s_ha_dum
    Commented Jun 2, 2013 at 16:48
  • Thank you a lot for pointing that answer but I actually don't know what to do with it or how to add an array. I'm not that skilled at PHP. My solution it's a mash-up of other solutions I found elsewhere. Sorry!
    – Juanma
    Commented Jun 2, 2013 at 18:50

1 Answer 1

1

I believe this is correct:

$year = 2013;
$month = 0;
$qry = new WP_Query(
  array(
    'post_type'=>'post',
    'posts_per_page'=>-1,
    'orderby'=>'date',
    'order'=>'ASC',
    'ignore_sticky_posts' => true,
    'year' => $year,
  )
);

while ($month < 12) {
  $month++;
  echo date('M',strtotime('2000-'.str_pad($month, 2, '0', STR_PAD_LEFT).'-01 00:00:01')).'<br>';
  if ($qry->have_posts()) {
    while ($qry->have_posts()) {
      if (date('n',strtotime($qry->post->post_date)) == $month) {   
        echo " -- ";
        the_title();
        echo '<br />';
        $qry->the_post();
      } else {
        break;
      }
    }
  } 
}

Of course, you will need to set your $year to the year you actually want.

That should Loop through all twelve months, echoing each one, checking for posts that match in the $qry results.

To print only the month names and links to months having posts.

$year = 2013;
$month = 0;
$qry = new WP_Query(
  array(
    'post_type'=>'post',
    'posts_per_page'=>-1,
    'orderby'=>'date',
    'order'=>'ASC',
    'ignore_sticky_posts' => true,
    'year' => $year,
  )
);

$months = array();
if (!empty($qry->posts)) {
  foreach ($qry->posts as $p) { 
    $months[date('n',strtotime($p->post_date))] = $p->post_date;
  }
}

while ($month < 12) {
  $month++;
  $monthname = date('M',mktime(0,0,0,$month,1,$year));
  echo '<li>';
    if (isset($months[$month])) {
      echo '<a class="year" href="'.get_month_link($year,$month).'" />'.$monthname.'</a>'.'<br>';
    } else {
      echo $monthname.'<br>';
    }
  echo '</li>';
}
5
  • Thank you! However this prints twelve months and the post titles for each month. Like this: Jan --Post Title Feb Mar Apr --Another Post title --Another Post Title May Jun.. an so on. What I pretend is to print exactly this: 2013: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ...and if a month has posts simply the output for the month is a link to filter the posts of that month for example if May has posts the word "May" is a link to myblog/2013/05
    – Juanma
    Commented Jun 2, 2013 at 21:34
  • @Juanma : See the edit.
    – s_ha_dum
    Commented Jun 2, 2013 at 22:00
  • Thank you again! I think I just need to asjust the output to fit the design but I'm worried about one thing... It's necessary to indicate the year? Whats would happen in 2014? What I need to happen is this: 2015: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 2014: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 2013: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
    – Juanma
    Commented Jun 2, 2013 at 22:34
  • You can get the year dynamically with $year = date('Y'); if that is what you want.
    – s_ha_dum
    Commented Jun 2, 2013 at 23:08
  • Great! Thank you for taking care for this problem! It works great! I tested and adjusted to my own needs and result is perfect except for one thing: it's printing only 2013 and I need to output all years and all 12 months for every years. By outputing all years I mean to show all years with posts. For example, if posts are found for 2013, 2012 and 2010 the it will print 3 rows one for each year and each row will show the 12 months.
    – Juanma
    Commented Jun 2, 2013 at 23:46

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.