Help splitting a custom post type archive into “past” and “upcoming”

The first thing we can do to make this more efficient, is to get rid of the query in your post type archive template. That page is already loading your events in the main query, and you’re then running a new query in the template, so this is a waste of a query.

What we’ll do instead is use the pre_get_posts action to add the meta query before the main query is run. We can then use the normal while( have_posts() ) loop in the template, and not the custom query loop. There’s an extra bit in here to handle past events that won’t make sense until the next step, so keep reading:

function event_post_order( $query ){
    // if this is not an admin screen,
    // and is the event post type archive
    // and is the main query
    if( ! is_admin()
        && $query->is_post_type_archive( 'event' )
        && $query->is_main_query() ){

        // if this is a past events view
        // set compare to before today,
        // otherwise set to today or later
        $compare = isset( $query->query_vars['is_past'] ) ? '<' : '>=';

        // add the meta query and use the $compare var
        $today = date( 'Y-m-d' );
        $meta_query = array( array( 
            'key' => 'sort_date',
            'value' => $today,
            'compare' => $compare,
            'type' => 'DATE'
        ) );
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'event_post_order' );

Now to get the past events working, we’ll add a couple of rewrite rules to handle events/past, plus pagination. Your archive-event.php template will be used for both upcoming and past, so no need for new templates.

This is also where we add the is_past rewrite tag, so we can check in the previous step if it’s a past events view:

function event_archive_rewrites(){
    add_rewrite_tag( '%is_past%','([^&]+)' );
    add_rewrite_rule(
        'events/past/page/([0-9]+)/?$',
        'index.php?post_type=event&paged=$matches[1]&is_past=true',
        'top'
    );
    add_rewrite_rule(
        'events/past/?$',
        'index.php?post_type=event&is_past=true',
        'top'
    );
}
add_action( 'init', 'event_archive_rewrites' );

So that’s it. Visit your Settings > Permalinks admin page after adding this code to your theme’s functions.php file to flush rewrite rules, or you could put it in a plugin.

techhipbettruvabetnorabahisbahis forumuedueduseduedueduedusedusedusedusedus