0
votes

I'm currently excluding all posts from the category 'featured' in my homepage loop using the following function:

function main_loop_excludes($query){
  if($query->is_main_query() && $query->is_home()){
    //'featured' cat ID = 531
    $query->set('cat','-531');
  }
}

add_action('pre_get_posts','main_loop_excludes');

This works perfectly, but I'd like to only filter out the most recent post rather than all posts from the 'featured' category. Is this possible?

I've seen ways to filter out specific posts using WP_Query, but I'm looking for a way to do it in the main Wordpress loop. pre_get_posts feels like the best starting point. Am I on the right track?


EDIT:

I've used the following code to save the ID of the specific post I want to exclude(saved as variable $post_to_exclude_ID):

$post_ids = get_posts(array(
  'numberposts'   => -1, // get all posts.
  'category_name' => 'featured',
  'fields'        => 'ids', // Only get post IDs
));
// post ID = 2162
$post_to_exclude_ID = $post_ids[0]; // Save ID of most recent post

And now I can use the original main_loop_excludes function to filter the main loop to show only the post in question, but I can't seem to reverse the process. Adding a minus sign before the ID just breaks the function (the loop then shows all posts, ).

New function:

function main_loop_excludes($query){
  if($query->is_main_query() && $query->is_home()){
    // Make sure the var is accessible
    global $post_to_exclude_ID;
    // Set the filter
    $query->set('p', $post_to_exclude_ID);
  }
}
add_action('pre_get_posts','main_loop_excludes');

This does not work:

$query->set('p', '-2162');

But the same style code does work for categories:

$query->set('cat','-531');

NB: thanks to Valerius for suggesting the idea of finding the post ID and injecting it into the $query->set... with a var.

2

2 Answers

1
votes

You can find the latest post of a specific category using wp_get_recent_posts().

With that, we can do the following:

function main_loop_excludes($query){
  $latest_featured = wp_get_recent_posts(array('numberposts' => 1, 'category' => 531));
  if($query->is_main_query() && $query->is_home()){
    //'featured' cat ID = 531
    $query->set('post__not_in',array($latest_featured[0]['ID'])); //exclude queries by post ID
  }
}

add_action('pre_get_posts','main_loop_excludes');
1
votes

here is a function that does just that:

    function get_lastest_post_of_category($cat){
    $args = array( 'posts_per_page' => 1, 'order'=> 'DESC', 'orderby' => 'date', 'category__in' => (array)$cat);
    $post_is = get_posts( $args );
    return $post_is[0]->ID;
}

Usage: say my category id is 22 then:

$last_post_ID = get_lastest_post_of_category(22);

you can also pass an array of categories to this function.