← W4DEV JOURNAL

Displaying WordPress Future Posts

WordPress doesn’t include future (scheduled) posts on Blog, Archive, Widget or Single post pages. That is the logical default. But if you ever need to display a list of future posts, and even show a future post on its single post page, here is a solution.

Shortcode to display the list of future posts

function future_postlist_shortcode( $atts ) {
    extract( shortcode_atts( array(
        'post_type' => 'post',
        'total'     => '-1',
        'order'     => 'DESC',
        'orderby'     => 'date',
    ), $atts ));


    $html  = '';
    $query = new WP_Query( array(
        'order'         => $order,
        'orderby'         => $orderby,
        'post_type'         => $post_type,
        'post_status'         => 'future',
        'posts_per_page'    => $total
    ));

    if( $query->have_posts() ):
    $html .= '<ul>';
        while( $query->have_posts()) : $query->the_post();
        $html .= sprintf(
            '<li><a href="%1$s">%2$s</a> -
            <span title="will be available within %3$s">in %3$s</span></li>',
            get_permalink(),
            get_the_title(),
            human_time_diff( strtotime(get_post()->post_date), current_time('timestamp') )
        );
        endwhile;
    $html .= '</ul>';
    wp_reset_postdata();
    endif;

    return $html;
}
add_shortcode( 'future_postlist', 'future_postlist_shortcode' );

The shortcode supports a few arguments – number of posts to show, order & orderby. You can use it like –

[future_postlist total='10' orderby='date' order='ASC']

This displays the list of future posts with a human readable publishing time, ex: in 9 hours, and the post title linked to the post page. But there is one problem – non logged-in users can not see future posts on the single post page, and for that we need some more code.

Display future posts for non logged-in users

On the single post page, non logged-in users do not see future posts. Here we filter the condition and allow non logged-in users to see a future post on its single post page.

add_filter( 'the_posts', 'myplugin_the_future_posts', 10, 2 );
function myplugin_the_future_posts( $posts, $query ) {
    global $wpdb;

    // We will skip if -
    // - there's already found posts
    // - or it isn't a single post page
    // - or User is loggedin
    if ( !empty($posts) || ! $query->is_singular() || is_user_logged_in() ) {
        return $posts;
    }

    if( $post_name = $query->get('name') ) {
        $post_type = $query->get('post_type') ? $query->get('post_type') : 'post';
        $post_status = 'future';
        $post_ID = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type= %s AND post_status= %s", $post_name, $post_type, $post_status ) );
        if( $post_ID ){
            $posts = array( get_post($post_ID) );
        }
    }

    return $posts;
}

All of the code used here should be added to your plugin or your theme’s functions.php file.

Filed under

KEEP EXPLORING

More practical tools for WordPress.

Browse the complete journal or find a focused plugin for your next project.