WP_Query: Get Posts by Relative Date
Posted: April 11, 2013 Filed under: WordPress Development 1 CommentSomeone asked me today how to use WP_Query to get posts by a relative date. The codex provides an example on how to achieve this. Heres what is shown on the codex.
<?php /** NOTE: This is the example from the Codex, which think is BAD. **/ | |
// Create a new filtering function that will add our where clause to the query | |
function filter_where( $where = '' ) { | |
// posts in the last 30 days (hardcoded) | |
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'"; | |
return $where; | |
} | |
//Requires immediate additiona and removal of the filter for intended use. | |
add_filter( 'posts_where', 'filter_where' ); | |
$query = new WP_Query( $query_string ); | |
remove_filter( 'posts_where', 'filter_where' ); |
I feel that its sloppy and not very flexible. Having to add the filter and remove it each time you want to do this is ugly. I solved this some time ago and had to dig through some old code to find it.
<?php | |
/** | |
* Allows WP_Query to use a 'since' argument to query for | |
* relative date queries. | |
* | |
* Usage: Query posts from last 30 days | |
* $query = new WP_Query('since' => '-30 days'); | |
* | |
* @uses strtotime() | |
* @author Eddie Moya | |
**/ | |
function filter_where_add_since( $where = '', $query) { | |
if( isset($query->query_vars['since']) ){ | |
$where .= " AND post_date > '" . date('Y-m-d', strtotime($query->query_vars['since'])) . "'"; | |
} | |
return $where; | |
} | |
add_filter( 'posts_where', 'filter_where_add_since', 10, 2 ); |
Ultimately what I have done is the same solution, using the same filter, and utilizing strtotime() to get the relative date. However i’ve wrapped it into a simple “since” parameter that can be used on any query. Just a little nicer and simpler to use.
This technique can easily be adapted to other custom parameters which result in modifications to the where or join filters.
I always find it annoying to filter for querying, but that’s a nice trick filtering on a query_var. Also see #18694