I need to maintain pagination for use with infinite scroll.

Is there no way to tell query_posts to retrieve sticky posts first?

It seems to be default behaviour on a standard wordpress blog on the home page, but becomes a bit awkward on a custom template for a page from what I can tell.

Thank you.

Edited to show current query:

query_posts( array( 
    'post_type' => array('post', 'careers-post'),
    'paged' => $paged,
    'posts_per_page' => 6,
    'category__in' => $page_categories,
    'ignore_sticky_posts' => 0
) );

Edit 2: Seems like "category__in" has a conflict with sticky posts dating back a long time: http://wordpress.org/support/topic/category_in-ampamp-sticky

Just to confirm, removing "category__in" does indeed let sticky posts bubble to the top as expected, but obviously doesn't solve the problem.

  • Add 'ignore_sticky_posts' => 0 in your query_posts . Commented Feb 19, 2013 at 10:20
  • I'd already tried that, seems to have no effect at all. The post set to sticky still loads as normal further down.
    – Kayo
    Commented Feb 19, 2013 at 10:24
  • Can you show your query_posts code? Commented Feb 19, 2013 at 10:25
  • have edited to include in original post
    – Kayo
    Commented Feb 19, 2013 at 10:28
  • 1
    You should scrap "query_posts" for the "pre_get_posts" action. So you aren't doing multiple queries. Also query_posts doesn't always get the pagination updated correctly. developer.wordpress.com/2012/05/14/…
    – Jake
    Commented Feb 21, 2013 at 17:22

1 Answer 1


Digging through the source code I couldn't really find any weird logic that would cause 'category__in' to break the ordering of the results. If you do, you might as well file a bug in the WordPress Trac.

It's also hard to reproduce this sort of issue, because it might depend on another issue which is specific to your database or how the data was previously manipulated by custom code.

Regardless, with a bit of effort you can always work around this kind of issue. Here's something that will filter your query results and send sticky posts to the top:

add_filter('the_posts', 'bump_sticky_posts_to_top');
function bump_sticky_posts_to_top($posts) {
    $stickies = array();
    foreach($posts as $i => $post) {
        if(is_sticky($post->ID)) {
            $stickies[] = $post;
    return array_merge($stickies, $posts);

Since your limiting the query to 6 posts, I don't foresee any significant impact on processing time. You can also put additional checks inside the function so this filter will only run when you're using that specific query (although if you don't the worst I can imagine happening is doubling-up on something that WP has already done).

Hope it helps! Let us know how it goes.

  • We actually came up with a different solution that worked for us, but upon further testing it seems as though your solution works too. We ended up using regex to modify the wordpress query directly inserting our own sql commands (I'll try and write a seperate post about it). I would give you the bounty but apparently I need to wait another 18 hours!
    – Kayo
    Commented Feb 21, 2013 at 15:48
  • 1
    The function/filter answer above makes WordPress 3.8.1 throw this error: Warning: array_merge(): Argument #1 is not an array [theme path to functions.php] [line number] Any thoughts on how to make this work? Commented Feb 4, 2014 at 17:57
  • @anned. Why don't you put that into its own question and we'll find you an answer? ;) Be sure to link it here in the comments so that people can follow the trail and find a solution regardless of WP version. Commented Feb 4, 2014 at 20:43
  • 3
    @A.Dougherty I've edited the code to fix that error.
    – Dan Searle
    Commented Nov 30, 2016 at 10:45

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