Here’s a way to force the exact posts_per_page
value in WP_Query
, regardless of sticky posts or custom post injects:
$args = [
'posts_per_page' => 1,
'_exact_posts_per_page' => true // <-- our custom input argument
];
by using our custom _exact_posts_per_page
input argument.
I’m sure this has been implemented many times before, but I didn’t find it at the moment, so let us try to implement it with this demo plugin:
<?php
/**
* Plugin Name: Exact Posts Per Pages
* Description: Activated through the '_exact_posts_per_page' bool argument of WP_Query
* Plugin URI: http://wordpress.stackexchange.com/a/257523/26350
*/
add_filter( 'the_posts', function( $posts, \WP_Query $q )
{
if(
wp_validate_boolean( $q->get( '_exact_posts_per_page' ) )
&& ! empty( $posts )
&& is_int( $q->get( 'posts_per_page' ) )
)
$posts = array_slice( $posts, 0, absint( $q->get( 'posts_per_page' ) ) );
return $posts;
}, 999, 2 ); // <-- some late priority here!
Here we use the the_posts
filter to slice the array, no matter if it contains sticky posts or not.
The the_posts
filter is not applied if the suppress_filters
input argument of WP_Query
is true
.
Note that query_posts()
is not recommended in plugins or themes. Check out the many warnings in the Code reference here.
Hope you can test it further and adjust to your needs!