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.

With the following code (in functions.php) my posts (of CPT event) are ordered by _end_date instead of _start_date. What's the proper solution to this as of WP 3.1.3? Of course I'd like to avoid using deprecated meta_key.

add_filter( 'pre_get_posts', 'my_get_posts' );
function my_get_posts( $query ) {
if ( is_home() ) {
  $query->set( 'post_type', 'event' );
  $query->set( 'meta_key', '_start_date' );
  $query->set( 'orderby', 'meta_value_num' );
  $query->set( 'order', 'ASC' );
  $query->set( 'meta_query', array(
                                   array(
                                         'key' => '_end_date',
                                         'value' => time(),
                                         'compare' => '>=',
                                         'type' => 'numeric'
                                        )
                                   )
                              );
  }
  return $query;
}
share|improve this question

1 Answer 1

up vote 9 down vote accepted

This seems to be a bug in Wordpress. Wordpress actually modifies the meta_query if you specify orderby and meta_key as query vars. Normally this modification adds the new meta_key as the first array in meta_query array and hence the orderby is applied to the first meta key specified in meta_query.

But when you modify orderby, meta_key and meta_value query_vars in pre_get_posts filter, due to the (it seems to me) bug in Wordpress, it add the new array in existing meta query but the new array is not inserted as first array, it gets appended to the existing meta_query. And orderby always gets applied to the first meta_key in meta_query.

So as a workaround until the bug gets fixed you can specify the meta_key again in the meta_query as the first array, as in the following example:

add_filter( 'pre_get_posts', 'my_get_posts' );
function my_get_posts( $query ) {
if ( is_home() ) {
  $query->set( 'post_type', 'event' );
  $query->set( 'meta_key', '_start_date' );
  $query->set( 'orderby', 'meta_value_num' );
  $query->set( 'order', 'ASC' );
  $query->set( 'meta_query', array(
        array(
              'key' => '_start_date'
        ),
        array(
              'key' => '_end_date',
              'value' => time(),
              'compare' => '>=',
              'type' => 'numeric'
        )
  ));
  }
  return $query;
}
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.