I would like to know how to remove posts from a certain category from my homepage after a certain time period (but not expiring the posts).

My site is currently set to display my latest blog posts from category "Basic".

The "Basic" category has the following sub categories:


-- Announcements

-- Company Specific

-- Industry

-- Other

-- Third Party

-- -- Fisco

"Third Party" subcategory has weekly posts. All of the other subcategories combined add up to a weekly post. Consequently, half of my homepage content is from "Third Party" subcategory. I would like to set this up so that "Third Party" posts are removed from the homepage after 14 days.

  • well that is possible, but not easy to get. here is some sort of answer (i strongly recommend #1) and you would have to use the pre_get_posts filter, to get it working. edit your question with your tryouts or create a new question with more specific problems and somebody will help you out :)
    – honk31
    Jul 12, 2018 at 9:04

1 Answer 1


This looks straightforward, but unfortunately isn't, because wp_query doesn't allow you to exclude posts on basis of multiple arguments (in this case category and date). You can select on basis of multiple arguments, but not exclude. So, to do what you want, you must in some way bundle your two arguments into one. Conceptually, you select the posts you do not want and then use that list to exclude them on basis of their ID's. Here we go:

add_action ('pre_get_posts', 'wpse308323_multiple_exclude', 10, 1);
function wpse308323_multiple_exclude ($query) {
  // only do this on home page for main query
  if ( $query->is_home() && $query->is_main_query() && ! is_admin() ) {
    // define posts to exclude and get them
    $args = array (
      'category_name' => 'third-party',
      'date_query' => array(
          'before' => '2 weeks ago'
    $q2 = new WP_Query ($args);
    // extract an array of ID's from the posts retrieved in $q2
    $q2_ids = wp_list_pluck ($q2->$posts,ID);
    // exclude these ID's from the main query
    $query->set ('post__not_in', $q2_ids);

Disclaimer: above code is given to show the concept. I haven't tested it, so debugging may be necessary. Some references:

  • 1
    We might note that $query->is_main_query() is an important check, to avoid a recursive loop, when instantiating a secondary WP_Query within a pre_get_posts callback for the main query. We might also simplify with 'fields' => 'ids'.
    – birgire
    Jul 12, 2018 at 11:13
  • that is a valid solution, but it requires two queries. no offense, but to me this looks fugly..
    – honk31
    Jul 12, 2018 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.