The other day, I was in the process of setting up some custom post meta for an event post type. I needed to add a start date/time and an end date/time for the event as custom meta information. Once I got all of that set up, I needed to modify the loop so that it retrieved the events in order of their start date/time; but I also needed to make sure I only retrieved events that hadn’t yet ended (based on their end date/time).
In the past, this wasn’t really possible with WordPress. You could either order posts by a custom meta value, or you could limit your query to posts that had a specific custom meta value, but you couldn’t do both. Then, in version 3.1 of WordPress, the meta_query was introduced to the WP_Query class. Now, however, you can use the traditional orderby and meta_key properties to sort your posts by a specific meta value; and you can use the
meta_query property to limit the posts that are returned.
In my case, wanting to sort the posts in ascending order according to the start date/time (which is stored in the MySQL datetime format of YYYY-MM-DD HH:MM:SS) and wanting to limit the posts to items that had an end date/time that had not yet occurred, I used the following properties:
array( 'orderby' => 'meta_value', 'meta_key' => '_event_start', 'order' => 'ASC', 'meta_query' => array( array( 'key' => '_event_end', 'value' => current_time( 'mysql' ), 'compare' => '>=', 'type' => 'DATETIME', ), ), );
If you need to sort your posts according to a numerical value, you should use
meta_value_num as your orderby property instead of using meta_value. For instance, if I was storing the start and end date/times as Unix timestamps instead of MySQL datetime values, I would have needed to use
meta_value_num to get them back in the correct order.