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'm using pre_get_posts to adjust the number of posts displayed on my homepage.

function lifelounge_query_adjust( $query ) {
    if ( is_home() ) {
        set_query_var( 'posts_per_page', 12 );
        return;
    }
}
add_filter( 'pre_get_posts', 'lifelounge_query_adjust' );

But I am running into a problem with sticky posts. Basically, if I have any sticky posts, the query will display more than the 12 posts I have specified, because it will display 12 plus any sticky posts. I could, of course, ignore sticky posts:

function lifelounge_query_adjust( $query ) {
    if ( is_home() ) {
        set_query_var( 'posts_per_page', 1 );
        set_query_var( 'ignore_sticky_posts', 1 );
        return;
    }
}
add_filter( 'pre_get_posts', 'lifelounge_query_adjust' );

But I don't think this is ideal. I think the sticky posts should be included in the limit of 12 posts, and not added to the limit. That is what makes the most sense to me. Is there a way to achieve that? Have I made a face-palm-worthy error?

Pretty much a duplicate of: Sticky Posts & Posts Per Page but that was weirdly closed as too localized. I disagree, obviously because I'm looking for an answer, but also because it is a question of why WordPress doesn't seem to respect the posts_per_page limit if you are using sticky posts. If you want 12 posts per page you should get 12, not 13, which is what you would get if you had a single sticky post.

share|improve this question
add comment

1 Answer

up vote 6 down vote accepted

Here is an approach to account for sticky posts by getting the number of sticky posts (if any) and include that in the calculation posts_per_page parameter:

add_action('pre_get_posts', 'ad_custom_query');
function ad_custom_query($query) {

    if ($query->is_main_query() && is_home()) {

        // set the number of posts per page
        $posts_per_page = 12;
        // get sticky posts array
        $sticky_posts = get_option( 'sticky_posts' );

        // if we have any sticky posts and we are at the first page
        if (is_array($sticky_posts) && !$query->is_paged()) {

            // counnt the number of sticky posts
            $sticky_count = count($sticky_posts);

            // and if the number of sticky posts is less than
            // the number we want to set:
            if ($sticky_count < $posts_per_page) {
                $query->set('posts_per_page', $posts_per_page - $sticky_count);

            // if the number of sticky posts is greater than or equal
            // the number of pages we want to set:
            } else {
                $query->set('posts_per_page', 1);
            }

        // fallback in case we have no sticky posts
        // and we are not on the first page
        } else {
            $query->set('posts_per_page', $posts_per_page);
        }
    }
}

Edit

In the case where the number of posts per page we wish to set is less than or equal to the number of sticky posts, I have set the posts_per_page to one and that will result in 13 or more posts $sticky_count + 1 (in this case) only on the first page (subsequent pages will have 12 posts). Maybe that is OK since this case is rare and +1 post on the first page may not be that significant.

This is because Wordpress will display all sticky posts first and on one page (the first page) even if their count is greater than the posts_per_page parameter, so we set the posts_per_page in this case to the minimal amount possible which is 1, because 0 and negative values will disable the posts_per_page parameter and that will make Wordpress to display all posts on the first page.

share|improve this answer
    
Great!! I think you need to change $sticky_count + (12 - $sticky_count) to 12- $sticky_count though. For example if I have 1 sticky, then your math still works out to 12, and then WP adds the sticky post to make 13. Oh, and if if ($sticky_count > $posts_per_page) and we set to 12, won't that mean we'll show 24+? –  helgatheviking Dec 19 '12 at 19:44
    
@helgatheviking: you are right. I always make such silly mistakes, calculations was never that interesting to me. And yes, that would result in 24 posts. I have updated the code to account for that, and I added a check for a page number. This works fine, but now there will be one case where $posts_per_page will be equal to $sticky_count, and here I set the posts_per_page parameter to be 1, and that I think will be OK since this case maybe rare and that will be only on the first page ($sticky_count + 1). –  Ahmad M Dec 19 '12 at 21:25
    
Thanks for the edit! I think this is the best solution we can get using sticky posts. I think that I might eventually sort by a simple meta key for whether a post is featured or not. That behaves more normally for my understanding. –  helgatheviking Dec 20 '12 at 0:52
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.