wp_query should show stickies first

I have the problem that my theme is for some reason always showing the latest posts at first. I would however like it to show all stickies at first and then show the regular ones. Here is the code:

<!-- Begin top thumbnails --> 
<div class="home-thumbs" style="width:<?php echo $top_width; ?>px;">  

<?php 
$home_query = new   WP_Query("cat=$slider_cat&ignore_sticky_posts=0&showposts=$top_row_posts"); $i = 0;?>
<ul class="thumbs" style="width:<?php echo $top_width; ?>px;">
<?php while ($home_query->have_posts()) : $home_query->the_post();
    $do_not_duplicate = $post->ID; $i++; ?>     
<li class="post-<?php the_ID(); ?> thumb-big">
<dl class="captioned-image"><dt>
<?php get_the_image( array( 'custom_key' => array( 'thumbnail' ), 'default_size' =>   '320x320', 'width' => '320', 'height' => '320' ) );?></dt>
<dd><span><?php echo get_the_title(get_the_ID());?></span></dd>
</dl>
</li>
<?php endwhile; wp_reset_query(); $i = 0; ?>
</ul>
</div>

By setting sticky posts to zero I would expect it to show sticky posts at the beginning oif the loop but it seems that the loop counter for some reason descends through the post id’s and simply showing the latest posts first, ignoring all my wp_query args.

Related posts

Leave a Reply

1 comment

  1. Well for starters, the query arg showposts has been replaced by posts_per_page since WP v2.1

    I don’t think any of your query args are being ignored (well, maybe save showposts; I haven’t checked to see if backwards compatibility support still exists for the arg). That said, I do not know what value your $top_row_posts variable holds or what it is supposed to represent, but it’s entirely possible that the data is being inserted into the query in a format unusable by WordPress.

    But (as Milo has corrected me) you are correct, setting ignore_sticky_posts to 0 should ensure that sticky posts are bubbled to the top. From the codex WP_Query page,

    ignore_sticky_posts: […] Note: ignore/exclude sticky posts being
    included at the beginning of posts returned, but the sticky post will
    still be returned in the natural order of that list of posts returned
    .

    While I’m not entirely sure what’s going wrong with your query, I propose a work-around using two separate queries that would explicitly ensure the desired effect – one for the sticky posts, and a separate for the rest:

    The ideal way to implement a dual-query approach would be to modify the main query using the pre_get_posts action in a plugin or your theme’s functions.php file, and then run your second “sticky” query directly in your theme’s home-page/front-page template. Something along the lines of

    functions.php:

    function modify_home_query( $query ) {
        /* If not displaying the home/front page or not processing the main query, bail out. */
        if( is_admin() || !$query->is_main_query() || !( is_home() || is_front_page() ) )
            return;
    
        /* If this is the main query for the home/front page, tell it to ignore sticky posts entirely. */
        $query->set( 'post__not_in', get_option( 'sticky_posts' ) );
    }
    add_action( 'pre_get_posts', 'modify_home_query' );
    

    Note that the WP_Query method is_main_query() is only available as of WP v3.3.

    Above the main loop in front-page.php or home.php or index.php (with conditional encapsulation):

    $stickyQuery = new WP_Query( array(
            'cat'                    => $slider_cat,    //Select posts from the slider category id
            'ignore_sticky_posts'    => 0,
            'post__in'               => get_option( 'sticky_posts' ),
            'posts_per_page'         => -1             //Get ALL the stickies
        );
    while( $stickyQuery->have_posts() ) : $stickyQuery->the_post();
    
       //... ( Sticky Post Template Here )
    
    endwhile;
    wp_reset_query();
    
    //... ( Main template loop here )
    

    As Milo has pointed out, regardless of whether you choose to focus on correcting your query or creating a work-around, you may wish to double check the value of your $slider_cat variable to make sure it is a valid category ID.