I have a custom WP_Query loop that I use for the main archive page. How can I filter the custom query to diplay posts from within 2 days +/- of one year ago from todays date?

My current query:

$posts_args = array( 
    'post_type' => 'album',
    'post_status' => 'published',
    'paged' => $paged,
    'order' => strtoupper($album_sort),
    'orderby' => 'date'

I know that the codex lists this time parameter for WP_Query but I've never used a loop filter and am a little confused on the implementation.

// Create a new filtering function that will add our where clause to the query
function filter_where( $where = '' ) {
    // posts  30 to 60 days old
    $where .= " AND post_date >= '" . date('Y-m-d', strtotime('-60 days')) . "'" . " AND post_date <= '" . date('Y-m-d', strtotime('-30 days')) . "'";
    return $where;

add_filter( 'posts_where', 'filter_where' );
$query = new WP_Query( $query_string );
remove_filter( 'posts_where', 'filter_where' );

Any assistance is appreciated.


Filters allow you to change data as it is being used by the wordpress core. This is a huge part of what gives wordpress so much flexibility.

add_filter() has 2 main parameters, the filter's hook and the callback function. When the filter is executed, all the callbacks associated with that filter will be executed.

Naturally, the filter needs to pass out some data and then look for a response. This particular filter is on $where, so that is passed in, and then returned after the callback function has modified it.

$where contains a portion of the final query string which is used by WP_Query when the query() method is called. By modifying this, you are able to perform filtering which isn't directly possible with WP_Query itself (like advanced date filtering).

In your case, what you're going to want to do is something like this:

function wpse46066_filter_where( $where = '' ) {
    // posts  30 to 60 days old
    $where .= " AND post_date >= '" . date('Y-m-d', strtotime('-1 year -2 days')) . "'" .
        " AND post_date <= '" . date('Y-m-d', strtotime('-1 year 2 days')) . "'";
    return $where;

add_filter( 'posts_where', 'wpse46066_filter_where' );
$query = new WP_Query( $post_args );
remove_filter( 'posts_where', 'wpse46066_filter_where' );

You'll notice that you don't actually change your query args at all, this is because the filter is operating independent of the input WP_Query is receiving from those args. You'll also notice that the filter is added, then applied (by calling WP_Query), then removed. This prevents all of your queries from having the same time restriction as this one.

A note on strtotime(): If you use multiple values, you must negate each of them. -1 year 2 days (assuming no leap year) is turned into 363 days, not 367. If you want to play with that, you can use this utility, which does a good job of showing you exactly what you're getting.


The add_filter() in this case will add content to the "where" clause to every single next WP_Query call.

The remove_filter() will kill that filter.

The example says "Add conditions to the 'where' clause of every next WP_Query", "Create new Wp_Query", "I don't want other WP_Query to be modified by my filter so kill it!"

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.