I'm trying to use URL parameters to modify the query for my "event" custom post type by using a function like the following:

function my_pre_get_posts($query)

    // do not modify queries in the admin

    if (is_admin())
        return $query;

    // only modify queries for 'event' post type

    if (isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'event')

        // allow the url to alter the query

        if (isset($_GET['city']))
            $query->set('meta_key', 'city');
            $query->set('meta_value', $_GET['city']);

    // return

    return $query;

add_action('pre_get_posts', 'my_pre_get_posts');

This works well when modifying the query with a string such as www.website.com/events?city=melbourne, but in my case I'd like to change the date range being queried from events that start on or after the current date to before the current date (using the custom field event_start_date). So my existing query looks like this:

$args = array(
        'post_type'     =>  'event',
        'ignore_sticky_posts'   => 1,
        'posts_per_page'        => 10,
        'post_status'           => 'publish',
        'paged' => get_query_var( 'paged' ),
        'orderby'       =>  'meta_value_num',
        'order'         =>  'ASC',
        'meta_query' => array(
                'key'     => 'event_start_date',
                'type'    => 'DATE',
                'value'   => current_time('Ymd'),
                'compare' => '>=',

Thus, how might I go about modifying the pre_get_posts function above to change the query by URL to '<=' the current date? Thanks for any assistance here.

  • are you asking how to unset and then set the compare of the meta_query? – hwl Aug 4 '17 at 14:59
  • @hwl yes, exactly- how would I modify the query to set the compare via URL to < than the event_start_date custom field from >=? Thanks. – nickpish Aug 4 '17 at 15:02
  • well, I was hoping to grab it directly, but didn't see a method. There could be one, but I've posted an answer that hopefully at least points in the right direction – hwl Aug 4 '17 at 16:21

I'm not where I can test this, but for something like: www.website.com/events?date=past, perhaps an approach like that outlined below could work.

(I can almost guarantee a type or two, so be sure to rewrite/edit/rework this into your function and ensure you don't inherit my errors).

   if (isset($_GET['date']))
           //using past, present, future as example. not sure what you wanted to pass in url
           switch( $_GET['date'] ) {
               case ('past'):
                     $compare = '<';
               case ('present'):
                     $compare = '=';
               case ('future'):
                     $compare = '>=';

           // $metas will be array of arrays, and we only want one of those,
          //  otherwise we risk altering the compare value of the city or 
         //  some other meta query array

          //get existing meta_query from $query
           $metas = $query->get('meta_query'); 
           foreach ( $metas as $meta ) {

            //limit edits to the one we want, when we want it
            if ( $meta['key'] == 'event_start_date' && $meta['compare'] != $compare ) {

                //might not need to unset, as setting it will overwrite
                unset( $meta['compare'] ); 

                $meta['compare'] = $compare;


          //now that foreach is over, re-set() the whole meta query
          $query->set( 'meta_query', $metas );

    }//if (isset)            


Also, be mindful that your

if (isset($_GET['city']))
    $query->set('meta_key', 'city');
    $query->set('meta_value', $_GET['city']);

might be overwriting an existing meta query (I'm unsure if adding it that way appends, prepends, or replaces anything being handled by WP_Meta_Query.) In any event, using $query->get('meta_query'); first can allow you to add another array of args to the meta_query:

$meta_query = $query->get('meta_query');
$my_new_meta_query = array(
                               'key'     => 'city',
                               'value'   => $_GET['city'],
$meta_query[] = $my_new_meta_query;

I only add that in case your intention was to build meta queries with url params such as www.website.com/events?date=past&city=melbourne. etc.

  • thanks very much for the answer @hwl- I've added your solution, but PHP is throwing an error of Call to undefined function set()- any ideas? – nickpish Aug 4 '17 at 17:09
  • oh wait, brain lapse on my end. just do: $meta['compare'] = $compare; – hwl Aug 4 '17 at 17:27
  • hm, no more PHP error, but now all url parameter variants, e.g. website.com/events?date=past are returning all results? – nickpish Aug 4 '17 at 17:44
  • lets make sure these are changing correctly. BEFORE the foreach, add a print_r( $metas) and then AFTER $query->set( 'meta_query', $metas ); add a $metas = $query->get('meta_query'); print_r($metas); and see if you can confirm that. – hwl Aug 4 '17 at 17:56
  • I'm wondering if perhaps an additional $query->set needs to be applied? If I add $query->set('meta_value', $_GET['date']); under $query->set( 'meta_query', $metas ); it returns no results, but clearly the query is at least being modified... – nickpish Aug 4 '17 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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