How to display all posts divided/ordered by post date? [closed]

You should be able to achieve this with something like the below…

<?php
    $wpb_all_query = new WP_Query( [
        'post_type'=>'post',
        'post_status'=>'publish',
        'posts_per_page'=> -1,
        'orderby' => 'date',
        'order' => 'ASC'
    ] );

    $dividers = [];
?>

<?php if ( $wpb_all_query->have_posts() ) : ?>

    <div id="list_allposts">
        <?php while ( $wpb_all_query->have_posts() ) : $wpb_all_query->the_post(); ?>

            <?php $post_date = get_the_date( 'F Y' ); ?>
            <?php if ( !in_array( $post_date, $dividers ) ): ?>
                <?php $dividers[] = $post_date; ?>
                <div class="divider">
                    <?= $post_date; ?>
                </div>
            <?php endif ?>

            <!-- Post code here -->

        <?php endwhile; ?>
    </div>

<?php endif; wp_reset_postdata(); ?>

What this does is creates an array of “dividers” (formatted dates) and checks to see if they’ve been printed or not.

This method relies on the posts being ordered by date otherwise you’d end up with dividers occuring incorrectly.


If you want to allow for different ordering (e.g. by title) but keep them grouped/divided by month and year you can do something like…

<?php
    $wpb_all_query = new WP_Query( [
        'post_type'=>'post',
        'post_status'=>'publish',
        'posts_per_page'=> -1,
        'orderby' => $orderby,
        'order' => $order
    ] );

    $dates_map = [];

    foreach ( $wpb_all_query->posts as $item ) {

        $date_key = (int)get_the_date( 'Ym', $item );

        if ( !array_key_exists( $date_key, $dates_map ) ) {
            $dates_map[ $date_key ] = [
                'label' => get_the_date( 'F Y', $item ),
                'posts' => []
            ];
        }

        $dates_map[ $date_key ][ 'posts' ][] = $item;
    }

    ksort( $dates_map );

?>

<?php if ( !empty( $dates_map ) ) : ?>

    <div id="list_allposts">
        
        <?php foreach ( $dates_map as $map ): ?>
            <div class="divider">
                <?= $map[ 'label' ]; ?>
            </div>

            <?php foreach ( $map[ 'posts' ] as $post ): ?>
                <?php setup_postdata( $post ); ?>

                <!-- Code for each post here -->
                <?php the_title(); ?>

            <?php endforeach; wp_reset_postdata(); ?>

        <?php endforeach ?>

    </div>

<?php endif; ?>

What this does is creates a multidimensional array of posts grouped by date. Something like…

$dates_map = [
    202101 => [
        'label' => 'January 2021',
        'posts' => [
            object(WP_Post)[
                'ID' => 1,
                'post_title' = 'Post 1',
                // ...
            ],
            object(WP_Post)[
                'ID' => 2,
                'post_title' = 'Post 2',
                // ...
            ]
        ]
    ],
    202102 => [
        'label' => 'February 2021',
        'posts' => [
            object(WP_Post)[
                'ID' => 3,
                'post_title' = 'Post 3',
                // ...
            ],
            object(WP_Post)[
                'ID' => 4,
                'post_title' = 'Post 4',
                // ...
            ]
        ]
    ],
    // ...
];

The array keys are the year and month allowing us to order the groups in ascending order.

We then loop through each of the dates, printing the label and then creating another loop for each of the posts in that group. Using setup_postdata() we can emulate the standard WP_Query while loop.

Neither of these have been test but should point you in the right direction.