I'm running through a normal loop on one of my templates, and it displays a list of upcoming events with dates. I'd like the events that have passed to stay active, but not appear in my list of posts.

As it currently stands, I select a date for the event (custom field), compare that to the current date via PHP date function, and then if its passed, "continue" so we skip the loop. This is great, except my posts per page suffers from this. I'm not using a WP_Query loop, this is an archive template.

Code looks something like this:

if( have_posts() ) : while( have_posts() ) : the_post();

    // Post specific fields
    $date = get_post_meta( get_the_ID(), 'Date', true );
    $time = get_post_meta( get_the_ID(), 'Time', true );
    $cat = wp_get_object_terms(get_the_ID(), 'event-type');

    $todaysDate = date('n\/d\/Y');

    if( $date < $todaysDate ){

Any ideas on how I can accomplish this another way?

  • search this site for pre_get_posts. also, your date format should be yyyy/mm/dd to correctly order by date.
    – Milo
    Commented Apr 8, 2015 at 17:10

2 Answers 2


Use pre_get_posts to add a meta query to the main query:

function wpd_date_meta_query( $query ) {
    if( $query->is_post_type_archive( 'your_post_type' ) && $query->is_main_query() ){
        $meta_query = array(
                'key' => 'Date',
                'value' => date('Ymd'),
                'compare' => '>=',
                'type' => 'NUMERIC'
        $query->set( 'meta_query', $meta_query );
        $query->set( 'meta_key', 'Date' );
        $query->set( 'orderby', 'meta_value_num' );
        $query->set( 'order', 'ASC' );
add_action( 'pre_get_posts', 'wpd_date_meta_query' );

Also note that while your current date format may appear to function correctly, you will get unexpected results with any format other than yyyy-mm-dd, because it is simply an 8-digit numeric comparison. Alter just the year and you will see how the current format fails.

  • Maybe I didn't explain this correctly. My users have a custom field with this post type that allows them to set the date for an upcoming event. This is what I'm comparing with the current date.
    – la1ch3
    Commented Apr 8, 2015 at 20:40
  • yes, that's what meta queries are for.
    – Milo
    Commented Apr 8, 2015 at 20:59
  • Ahh, I see; I was unaware that meta_query even existed. Seems pretty powerful, actually. Thanks very much for your advice!
    – la1ch3
    Commented Apr 8, 2015 at 21:02

So I actually solved this myself. Its not the most elegant solution, but it works. I figured it would help somebody.

I first created a new post status using register_post_status() in functions.php. I then used pre_get_posts() also in functions.php, in which I filtered the main query on my archive page to only display posts of the status 'publish'.

Finally, on my actual archive page, is where things get a little tricky. I first created a secondary loop using a new WP_Query with my post_type as an argument, and grabbed the assigned date from each post. I compared the date of the event with today's date (php date() function) and if the event is past today's date (it already occured), then we assign that post a new post status of 'passed' (the post status I created earlier). This is done with the wp_transition_post_status() function. Finally, I run through my normal loop and all the correct posts are displayed. A little convoluted at the moment, but is a decent way of keeping an up-to-date list of events.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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