Zach Nicodemous
Zach Nicodemous

Reputation: 9497

WordPress - Get Posts by Date

I am trying to figure out how to construct a WordPress query that is going to get posts by date.

What I mean by this, is that I'd like a way to output my WordPress posts something like this:

<div class="day-posts">
     <div class="day">
          <div class="title">Monday 1st January 2014</div>
          <div class="posts">
               <div class="post">
                    <div class="title">Post for this day</div>
                    <div class="content">Lorum ipsum dolar sit amet</div>
               </div>
          </div>
     </div>
     <div class="day">
          <div class="title">Tuesday 2nd January 2014</div>
          <div class="posts">
               <div class="post">
                    <div class="title">Post for this day</div>
                    <div class="content">Lorum ipsum dolar sit amet</div>
               </div>
          </div>
     </div>
</div>

This needs to work with posts that are not published yet also, using the "post_status=future" query option.

I have spent about an hour searching online to see if someone has done something like this before, but unfortunatly I haven't found anything viable.

I have also made some attempts at this myself but unfortunatly, I haven't been able to come up with anything that works.

Does anyone have some suggestions or insights on how this might be done?

Thanks

Upvotes: 3

Views: 12768

Answers (2)

Danijel
Danijel

Reputation: 12719

Although at first glance it looks like a simple task, it is tricky to build a nested loop with a single query.

First step is to build a query, for the demonstration I will take all posts ( posts_per_page=-1 ) in ascending order ( order=asc ) with any post status ( post_status=any ). Post status can be changed by using array of arguments like 'post_status' => array( 'publish', 'future' ) ( documentation ).

Next step is to build multidimensional array of posts:

$posts_by_day = array_reduce( $query->posts, function( $r, $v ) {
    $r[ date( 'Y-m-d', strtotime( $v->post_date ) ) ][] = $v;
    return $r;  
});

An array that looks like:

    Array
    (
        [2014-03-17] => Array
            (
                [0] => WP_Post Object ( ... )
                [1] => WP_Post Object ( ... )
        )
        [2014-03-24] => Array
            ( 
                [0] => WP_Post Object ( ... )
                [1] => WP_Post Object ( ... )
                [2] => WP_Post Object ( ... )
        )
        ...
    )

And finally loop through an array, by date in the outer loop, and by posts on that date in the inner loop. setup postdata() is used to set up a global post data so that Template Tags can work in the current post context.

<?php
    $query = new wp_query( 'post_status=any&order=asc&posts_per_page=-1' );

    $posts_by_day = array_reduce( $query->posts, function( $r, $v ) {
        $r[ date( 'Y-m-d', strtotime( $v->post_date ) ) ][] = $v;
        return $r;  
    });
?>

<?php if ( $posts_by_day ) : ?>
    <div class="day-posts">
    <?php foreach( $posts_by_day as $day => $day_posts ) : ?>
        <div class="day">
            <div class="title"><?php echo date( 'l jS F Y', strtotime( $day ) ); ?></div>
            <div class="posts">
            <?php foreach( $day_posts as $post ) : setup_postdata( $post ); ?>
                <div class="post">
                    <div class="title"><?php the_title(); ?></div>
                    <div class="content"><?php the_content(); ?></div>
                </div>          
            <?php endforeach; ?>
            </div>
        </div>  
    <?php endforeach; wp_reset_postdata(); ?>
    </div>
<?php endif; ?>

Upvotes: 0

Demosthenes
Demosthenes

Reputation: 364

<?php
$query = new WP_Query(array('orderby' => 'post_date', 'order' => 'DESC')); //Orders posts by post_date in descending order

// The Loop
if ($query->have_posts()) {
    echo '<div class="day-posts">';
    while ($query->have_posts()) {
        $query->the_post();
        echo '<div class="day">';
        the_date('l jS F Y', '<div class="title">', '</div>'); //Formats date, before echo, after echo
        echo '<div class="posts">';
        echo '<div class="post">';
        the_title('<div class="title">', '</div>'); //echo title
        echo '<div class="content">';
        the_content(); //echo content
        echo '</div></div></div></div>';
    }
    echo '</div>';
}
?>

I put this together in a few minutes, sorry I didn't concatenate and make it all nice, but you can do that.

Upvotes: 1

Related Questions