3 Posts in Loop, Show Stickies First

Okay I am starting to wonder if it is even possible to do this! As I've found very little info on the matter online. This is a fresh WP install that I've been experimenting on so that I can work in a more simplified environment (rather than try to solve the full problem itself on my live client's website if that makes sense).

I'm trying to display a total of 3 posts using query_posts(). I want the sticky posts to show first, and then for the remainder of the loop to consist of none-stickies.

As you can see, it is loading too many posts (6 in total, which is all of the posts on the site):

http://www.matt-demo-wordpress.com.gridhosted.co.uk/?page_id=46

Here is the code I'm using:

?php wp_reset_query(); ?

?php

    // sticky posts first

    $sticky = get_option('sticky_posts');

    query_posts(array(
      'post__in' = $sticky,
      'posts_per_page' = 3,
      'post_type' = 'post'
    ));

    get_template_part('loop', 'query-sticky' );

?

?php

    // none-stickies for remainder of loop

    query_posts(array(
      'post__not_in' = $sticky
    ));

    get_template_part('loop', 'query-sticky-none' );

    wp_reset_query();

?

I assume that the second loop is trying to display 10 posts as per my settings in WP. I was hoping that the posts_per_page param in the first loop would maybe carry over to the second.

Because I of course can't specify posts_per_page again in the second loop as there would be more than 3 posts displayed overall.

Is it actually possible to get sticky posts to work in this way? Or is the only way to get them to work properly to use them on the 'posts' page in WordPress? Not using a custom query?

Topic wp-reset-query loop sticky-post query-posts query Wordpress

Category Web


Give this a try. It replaces query_posts(), which you should never use (it kills unicorns) with WP_Query.

Basically it first queries your sticky posts and then, if there were less than your required 3 posts, it will perform another query for the relavent number of posts.

/** Grab the sticky post ID's */
$sticky = get_option('sticky_posts');

/** Query the sticky posts */
$args = array(
    'post__in'          => $sticky,
    'posts_per_page'    => 3,
    'post_type'         => 'post'
);
$sq = new WP_Query($args);

/** Count the number of post returned by this query */
$sq_count = $sq->post_count;

/** Output your sticky posts */
get_template_part('loop', 'query-sticky'); // You'll need to globalize `$sq` in this template

/** Check to see if any non-sticky posts need to be output */
if($sq_count < 3) :

    $num_posts = 3 - $sq_count;
    
    /** Query the non-sticky posts */
    $sticky = get_option('sticky_posts');
    $args = array(
        'post__not_in'      => $sticky,
        'posts_per_page'    => $num_posts,
        'post_type'         => 'post'
    );
    $nq = new WP_Query($args);
    
    /** Output your non-sticky posts */
    get_template_part('loop', 'query-sticky-none'); // You'll need to globalize `$nq` in this template
    
endif;

"I don't want to globalize in my templates"

If you don't want to have to globalize the $sq and $nq variables in your templates, rather than get_template_part() you could use locate_template() -

locate_template('loop-query-sticky.php');
locate_template('loop-query-sticky-none.php');

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.