Enable future posts in wordpress single and archive pages

Posted on 16th September, 2017 Leave a Comment

This goes in a functions file.

<?php 
// Enable future posts in archives and posts
add_action( 'pre_get_posts', function ( $wp_query ) {
    global $wp_post_statuses;

    if (
        ! empty( $wp_post_statuses['future'] ) &&
        ! is_admin() &&
        $wp_query->is_main_query() && (
            $wp_query->is_date() ||
            $wp_query->is_single()
        )
    ) {
        $wp_post_statuses['future']->public = true;
    }
});


// Enable future posts links as pretty permalinks
add_filter( 'post_link', 'future_permalink', 10, 3 );

function future_permalink( $permalink, $post, $leavename ) {
    /* for filter recursion (infinite loop) */
    static $recursing = false;

    if ( empty( $post->ID ) ) {
        return $permalink;
    }

    if ( !$recursing ) {
        if ( isset( $post->post_status ) && ( 'future' === $post->post_status ) ) {
            // set the post status to publish to get the 'publish' permalink
            $post->post_status = 'publish';
            $recursing = true;
            return get_permalink( $post, $leavename ) ;
        }
    }

    $recursing = false;
    return $permalink;
}  


// join term_relationships and term_taxonomy
 add_filter( 'getarchives_join', 'customarchives_join' );
 // add where condition for date
add_filter('getarchives_where','show_future_posts');
 // add where condition for category
 add_filter( 'getarchives_where', 'customarchives_where' );

function customarchives_join($join_clause) {
 global $wpdb;
 return $join_clause." INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID =  $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
 }

function show_future_posts() {
 return "WHERE post_type = 'post' AND post_status = 'future'";
}

function customarchives_where($where_clause) {
 global $wpdb;
 $include = get_cat_ID('Match Previews');  // category id to include
 return $where_clause." AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id IN ($include)";
 }

// append "custom-string" to the URL of date archives
add_action( 'init', function() {
    global $wp_rewrite;
    $wp_rewrite->date_structure = 'custom-string/%year%/%monthnum%/%day%';
});

 ?>

 <?php 
        // Defined /wp-includes/general-template.php  #1663
        // Manipulating the wp_get_archives function
         function daily_get_archives( $args = '' ) { 
            global $wpdb, $wp_locale; 
         
            $defaults = array( 
                'type' => 'monthly', 'limit' => '',  
                'format' => 'html', 'before' => '',  
                'after' => '', 'show_post_count' => false,  
                'echo' => 1, 'order' => 'DESC',  
                'post_type' => 'post' 
         ); 
         
            $r = wp_parse_args( $args, $defaults ); 
         
            $post_type_object = get_post_type_object( $r['post_type'] ); 
            if ( ! is_post_type_viewable( $post_type_object ) ) { 
                return; 
            } 
            $r['post_type'] = $post_type_object->name; 
         
            if ( '' == $r['type'] ) { 
                $r['type'] = 'monthly'; 
            } 
         
            if ( ! empty( $r['limit'] ) ) { 
                $r['limit'] = absint( $r['limit'] ); 
                $r['limit'] = ' LIMIT ' . $r['limit']; 
            } 
         
            $order = strtoupper( $r['order'] ); 
            if ( $order !== 'ASC' ) { 
                $order = 'DESC'; 
            } 
         
            // this is what will separate dates on weekly archive links 
            $archive_week_separator = '–'; 
         
            $sql_where = $wpdb->prepare( "WHERE post_type = %s AND post_status = 'publish'", $r['post_type'] ); 
         
            /** 
             * Filters the SQL WHERE clause for retrieving archives. 
             * 
             * @since 2.2.0 
             * 
             * @param string $sql_where Portion of SQL query containing the WHERE clause. 
             * @param array  $r         An array of default arguments. 
             */ 
            $where = apply_filters( 'getarchives_where', $sql_where, $r ); 
         
            /** 
             * Filters the SQL JOIN clause for retrieving archives. 
             * 
             * @since 2.2.0 
             * 
             * @param string $sql_join Portion of SQL query containing JOIN clause. 
             * @param array  $r        An array of default arguments. 
             */ 
            $join = apply_filters( 'getarchives_join', '', $r ); 
         
            $output = ''; 
         
            $last_changed = wp_cache_get_last_changed( 'posts' ); 
         
            $limit = $r['limit']; 
         
           if ( 'daily' == $r['type'] ) { 
                $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date $order $limit"; 
                $key = md5( $query ); 
                $key = "wp_get_archives:$key:$last_changed"; 
                if ( ! $results = wp_cache_get( $key, 'posts' ) ) { 
                    $results = $wpdb->get_results( $query ); 
                    wp_cache_set( $key, $results, 'posts' ); 
                } 
                if ( $results ) { 
                    $after = $r['after']; 
                    foreach ( (array) $results as $result ) { 
                        $url = get_day_link( $result->year, $result->month, $result->dayofmonth ); 
                        if ( 'post' !== $r['post_type'] ) { 
                            $url = add_query_arg( 'post_type', $r['post_type'], $url ); 
                        } 
                        $date = sprintf( '%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth ); 

                        // Modifying the date output for the Match Previews
                        $text = '<div class="month">' . mysql2date( 'M', $date ) . '</div>'; 
                        $text .= '<div class="date">' . mysql2date( 'd', $date ) . '</div>';

                        if ( $r['show_post_count'] ) { 
                            $r['after'] = ' (' . $result->posts . ')' . $after; 
                        } 
                        $output .= get_archives_link( $url, $text, $r['format'], $r['before'], $r['after'] ); 
                    } 
                } 
            } 
            if ( $r['echo'] ) { 
                echo $output; 
            } else { 
                return $output; 
            } 
        } 
         ?>

If you’d like to display the future post dates with links to the archives use this:

<div class="daily-archives">
	<?php $args = array(
		'type'            => 'daily',
		'limit'           => '6',
		'format'          => 'custom', 
		'before'          => '<div>',
		'after'           => '</div>',
		'show_post_count' => false,
		'echo'            => 1,
		'order'           => 'ASC',
	    'post_type'     => 'post'
	);
	daily_get_archives( $args ); ?>
</div>

To display the posts archive we’ll need to add the dates to the query.

$year     = get_query_var('year');
$monthnum = get_query_var('monthnum');
$day      = get_query_var('day');

$today = getdate(); // Get todays date
$args = array(
	'posts_per_page' => -1,
	'date_query' => array( // Only show posts that are the dates posts
		array(
			'year'  => $year,
			'month' => $monthnum,
			'day'   => $day,
		),
	),
);
$future_query = new WP_Query( $args ); 

Leave a Comment

To preserve code added to a comment you can wrap your code in short tags
by using [square brackets]:

  1. PHP use - [php] <?php code here ?> [/php]
  2. CSS use - [css] #code-here {} [/css]
  3. HTML use - [html] <div> code here </div> [/html]
  4. JS use - [js] $(".codeHere") [/js]