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.

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.

share|improve this question
add comment

2 Answers

up vote 2 down vote accepted

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.

share|improve this answer
    
Thanks @m0r7if3r that makes a lot of sense! –  mattrepublic Mar 20 '12 at 23:42
add comment

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!"

share|improve this answer
add comment

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.