Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've setup a CPT to act the same ways as posts but used to post event details.

Thing is that some of the posts are in the future and such have a future date set on them. Problem is that normal users cannot see these posts.

So:

  • How do I alter archive-events.php to list future posts too? Showing far future posts first and oldest posts last while maintaining pagination.
  • How do I make it so that when a user clicks a future post they don't get a 404 page not found as the post is not technically published yet?
share|improve this question
4  
Would it be possible to use custom fields for the date rather than using the default wordpress functions as like you say essentially the posts with future dates aren't actually published in the view of WP. –  Vince Pettit Mar 2 '12 at 11:42
    
Although saying that it would seem like it is a user access level thing so you could possibly add something to the functions.php file to grant all users the ability to view future posts –  Vince Pettit Mar 2 '12 at 11:43

2 Answers 2

up vote 2 down vote accepted

I've been able to solve this myself. My entire code for registering the CPT:

<?php
add_action( 'init', 'events_post_type_register' );
function events_post_type_register() {

    $post_type = "events";

    $labels = array(
        'name' => _x('Events', 'post type general name', 'project_X'),
        'singular_name' => _x('Event', 'post type singular name', 'project_X'),
        'add_new' => _x('Add New', 'event', 'project_X'),
        'add_new_item' => __('Add New Event', 'project_X'),
        'edit_item' => __('Edit Event', 'project_X'),
        'new_item' => __('New Event', 'project_X'),
        'all_items' => __('All Events', 'project_X'),
        'view_item' => __('View Event', 'project_X'),
        'search_items' => __('Search Events', 'project_X'),
        'not_found' =>  __('No events found', 'project_X'),
        'not_found_in_trash' => __('No events found in trash', 'project_X'),
        'parent_item_colon' => '',
        'menu_name' => 'Events'
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'hierarchical' => false,
        'has_archive' => true,
        'rewrite' => array(
            'with_front' => false,
            'slug' => "news/{$post_type}"
        ),
        'supports' => array( 'title', 'editor', 'thumbnail' )
    );
    register_post_type($post_type, $args);

    remove_action("future_{$post_type}", '_future_post_hook');
    add_action("future_{$post_type}", 'sc_ps_publish_future_events_now', 2, 10);
}

function sc_ps_publish_future_events_now($depreciated, $post) {
    wp_publish_post($post);
}

add_filter('posts_where', 'sc_ps_show_future_events_where', 2, 10);
function sc_ps_show_future_events_where($where, $that) {
    global $wpdb;
    if("events" == $that->query_vars['post_type'] && is_archive())
        $where = str_replace( "{$wpdb->posts}.post_status = 'publish'", "{$wpdb->posts}.post_status = 'publish' OR $wpdb->posts.post_status = 'future'", $where);
    return $where;
}
?>

So to allow posts to be visable to all users even if they are set in the future you need to do the following:

remove_action("future_{$post_type}", '_future_post_hook');
add_action("future_{$post_type}", 'sc_ps_publish_future_events_now', 2, 10);

We remove the action that deals with posting later and apply our own action to force it to be published despite it having a future date with:

wp_publish_post($post);

Then all we now need to do is show future posts on the archive page by filtering posts_where:

function sc_ps_show_future_events_where($where, $that) {
    global $wpdb;
    if("events" == $that->query_vars['post_type'] && is_archive())
        $where = str_replace( "{$wpdb->posts}.post_status = 'publish'", "{$wpdb->posts}.post_status = 'publish' OR $wpdb->posts.post_status = 'future'", $where);
    return $where;
}
share|improve this answer
2  
Add a text domain to your __() calls or don’t use function. –  toscho Mar 2 '12 at 12:45
3  
-1 for approach. :) As per discussion in chat it would be more reliable to track event date separately in custom field over bending internal mechanics to makes use of post's date. –  Rarst Mar 2 '12 at 12:47
1  
+1 for alternative approach :) I totally agree with @Rarst but I'm also finding this approach interesting and I'll be happy to have it well documented here on WPSE. –  Michal Mau Mar 2 '12 at 12:59

Brady, I can't thank you enough for leading me to this solution. My client had already set all of the event dates without a custom field, and I wasn't about to go back and change everything. Your code initially threw an error when trying to post, but it worked with the following slight modifications (made to match the format used in wp-includes/post.php):

remove_action( 'future_' . $post_type, '_future_post_hook', 5, 2 );
add_action( 'future_' . $post_type, 'my_future_post_hook', 5, 2);

and

function my_future_post_hook( $deprecated = '', $post ) {
    wp_publish_post( $post->ID );
}

I spent awhile trying to figure this out. Hope it helps someone else!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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