0

I have a post type that holds a custom meta field with a date in it. The date is stored in the format: yyyymmdd.

On the archive page for this post type I want to create 12 separate containers, one for each month, and to display in each the posts matching the corresponding month.

My question was about looking for ideas to achieve what I wanted.

Thanks to Krzysiek Dróżdż idea, I did filter pre_get_posts and came up with this code in my archive template for the post type:

$posts_by_month = array()
while ( have_posts() ) : the_post();                                

    // get the post meta where the date is stored in yyyymmdd format                               
    $recurrence_date = strtotime( get_post_meta( $post->ID,'recurrence_futuredates_0_recurrence_from', true ) ); 
    // return the month only in '1-12' format
    $current_month = date( 'n', $recurrence_date );  

    // loop 12 months
    for ( $i=1; $i<=12; $i++ ) {

        if ( $current_month == $i ) {

             // store all the posts for the $current_month
             $posts_by_month[$current_month][] = array( 
                     'posts' =>  array( 
                                       'id' => $post->ID,
                                       'title' => get_the_title(),
                                       'permalink' => get_permalink(),
                      ),
             );

          }

     }   

endwhile;

// sort the month order         
ksort( $posts_by_month );


// loop 12 months
for ( $i=1; $i<=12; $i++ ) {

    // if there are no posts for current month, skip month 
    if ( $posts_by_month[$i] ) {

        ?>
        <i><?php echo $i; ?></i>
        <?php foreach ( $posts_by_month[$i] as $this_month[$i] ) : ?>

            <b><?php echo $this_month[$i]['title']; ?></b><br/>

        <?php endforeach;

    }

}

1 Answer 1

2

First of all I don't think you should use your custom query_posts in here. WordPress already queries posts on archive pages, so it's waste of time to query them one more time. You should be using pre_get_posts filter.

function my_pre_get_posts($query) {
  if (!is_admin() && is_main_query() '<YOUR_POST_TYPE>' === $query->query_vars('post_type')
         && $query->is_archive()) {
    $query->set('orderby','meta_value');
    $query->set('meta_key', '<YOUR_POST_TYPE>'); //formatted YYYYMMDD
    $query->set('ignore_sticky_posts', true);
  }
  return $query;
}
add_filter('pre_get_posts','my_pre_get_posts');

When your posts are selected, you can split them by month doing it manually in your loop. Somthing like this should solve your problem:

$prev_month = '';

while ( have_posts() ):
    the_post();
    $post_custom_date = strtotime(get_post_meta($post->ID, 'Deadline', true)); // this line may need to be changed - it depends on the format you choosed to store dates in deadline meta value
    $current_month = date('F Y', $post_custom_date );  
    if ( $current_month != $prev_month ) {
        echo '<h2>'. $current_month .'</h2>';
        $prev_month = $current_month;

    // output your post/event
endwhile;

It's not tested so it can be a little bit buggy, but the idea behind this solution should be clear.

1
  • thanks! that helped, I did edit my question with the code I came up with, using your example
    – unfulvio
    Commented Jun 25, 2013 at 2:20

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.