0

WordPress VIP and other development guides I've seen recommend avoiding the use of post__not_in for performance reasons when using WordPress at scale. Their suggestion is to filter out the posts in php:

$posts_to_exclude = [ 67, 68, 69 ];

$query = new WP_Query( [ 
    'post_type'      => 'post',
    'posts_per_page' => 5 + count( $posts_to_exclude ),
    'paged'          => get_query_var( 'paged' ),
] );

if ( $query->have_posts() ) :
    while ( $query->have_posts() ) :
        $query->the_post(); 
        if ( in_array( get_the_ID(), $posts_to_exclude, true ) ) {
            continue;
        }
        the_title();
    endwhile;
endif;

My question is how do you show the correct number of posts per page when filtering out the posts via php? The example above adds the count of the excluded posts to the posts_per_page variable. However this would result in there being between 5 – 8 posts per page depending on how many posts are excluded for a particular page. Is there a workable solution for making the number of posts per page consistent or is this optimisation only really meant for posts that aren't going to be paginated?

3 Answers 3

0
$limit = 5;

if ( $query->have_posts() ) :
    while ( $query->have_posts() ) :
        $query->the_post(); 
        if ( in_array( get_the_ID(), $posts_to_exclude, true ) && $limit > 0 ) {
            continue;
        }
        $limit--;
        the_title();
    endwhile;
endif;
0

If You want to keep posts limit and avoid parameter post_not_in You should add these code to filter posts in $query.

//get posts from query object
$posts = $query->posts;
//set limit of posts that You need on page
$limit = 5; 

//filter by ID that You want to exclude
$posts = array_filter($posts, function( $data ){ 
    if( ! in_array(  $data->ID, $posts_to_exclude ) )return true;
});

$posts = array_slice($posts, 0, $limit);
//put filtered posts in query object
$query->posts = $posts;
//here You can do Your loop
1
  • Please edit your answer, and add an explanation: why could that solve the problem?
    – fuxia
    Commented Aug 14, 2017 at 11:22
0

The truth here is: while you surely can remove the posts you do not want to have in your loop or after querying, you can not do so without messing up the pagination. If you want a correct loop and pagination, you won't be able to get around post__not_in. However, if your query is not that complicated (like multiple meta queries additional to the post__not_in), the performance won't be that affected. Sure, "NOT IN" statements are not that great, but they won't bring your websites performance that much down.

So, as long as you don't already have to fight slow response times, you probably can use this one post__not_in ;)

Your Answer

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

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