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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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