2

How can group posts by month and year by a separate headline?

Example (output with this date format):

Dezmber 2014
- 4. Dez 2014
- 5. Dez 2014

I have a custom field (datepicker) "event_date".

    <?php

$the_query = new WP_Query( array(
    'post_status' => 'publish',
    'meta_key'    => 'event_date',
    'orderby'     => 'meta_value'
) );

$current_header = '';

while ( $the_query->have_posts() ) :
    $the_query->the_post();

    $temp_date = get_post_meta( get_the_ID(), 'event_date', true );

    if ( $temp_date != $current_header ) {
        $current_header = $temp_date;
        echo "<div class='sub_category_name_wrapper'><h5>$current_header</h5></div>";
    }

    ?>

    <div class="event_content_wrapper">
        <ul>
            <li>        
                <span><?php the_field('event_date'); ?></span>&nbsp;<span><?php the_field('event_region'); ?></span>
                <h4><?php the_title(); ?></h4>
                <br>
                <?php the_excerpt(); ?>
                <a class="content_button" href="<?php the_permalink(); ?>">mehr</a>
            </li>
        </ul>
    </div>

<?php endwhile;

?>

2 Answers 2

6

When you query the posts with orderby argument as a event_date (it could be any field with date format) the posts are ordered by date, desc or asc. So the only thing you have to do afterwards is to group them by year and month.

So:

<?php

            $posts = get_posts(array(
                'post_type' => 'post',
                'meta_key'  => 'event_date',
                'orderby'   => 'meta_value_num',
                'order'     => 'DESC'
            ));

            $group_posts = array();

            if( $posts ) {

                foreach( $posts as $post ) {

                    $date = get_field('event_date', $post->ID, false);

                    $date = new DateTime($date);

                    $year = $date->format('Y');
                    $month = $date->format('F');

                    $group_posts[$year][$month][] = array($post, $date);

                }

            }

            foreach ($group_posts as $yearKey => $years) {

                echo $yearKey;
                echo '<br>';

                foreach ($years as $monthKey => $months) {

                    echo $monthKey;
                    echo '<br>';

                    foreach ($months as $postKey => $posts) {

                        echo $posts[1]->format('d-m-Y');
                        echo '<br>';
                        echo $posts[0]->title;
                        echo '<br>';
                    }

                }

            }

        ?>

You can change the year and month format to your desire. This is just a demonstration. The same applies for HTML formatting.

0

Following the advanced example on https://www.advancedcustomfields.com/resources/date-picker/ this worked for me:

There is a post type called 'event' with two acf custom fields 'event_date_start' and 'event_date_end'.

The query shows all future events from today on and every month gets its title. So you can say the events are grouped by month. Maybe this is not exaclty what you are asking for but at least it could be an interesting approach...

March 2017
- Event 1
- Event 2
- Event 3
April 2017
- Event 4
- Event 5
...

<?php 
$today = date('Ymd');


$args = array(
          'post_type'     => 'event',
          'posts_per_page'   => -1,
          'meta_key' => 'event_date_start',
          'orderby' => 'meta_value_num',
          'order' => 'ASC',
          'meta_query' => array(
            'relation' => 'OR',
              array(
                'key'   => 'event_date_end' , 
                'compare' => '>=',
                'value'   => $today,
                'type'        => 'date'
              ),
              array(
                  'key'   => 'event_date_start' , 
                  'compare' => '>=',
                  'value'   => $today,
                  'type'        => 'date'
              ),


            )
);
$shows = get_posts($args );


$current_header = '';

foreach ($shows as $post ) : setup_postdata($post); 

// get raw date
$date = get_field('event_date_start', false, false);


$temp_header = date_i18n('F Y', strtotime($date));

if ( $temp_header != $current_header ) {
    $current_header = $temp_header;
    echo "<h3>".$current_header.'</h3>';

}
// echo content of event
get_template_part('templates/content', 'events');
endforeach; 
wp_reset_postdata();

?>
2
  • Sorry but the answer has nothing to do with what the author asked.
    – Laxmana
    Mar 13, 2017 at 10:33
  • very nice. this is exactly what I was looking for.
    – Starfs
    Jan 14, 2020 at 4:32

Your Answer

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

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