Question

The following snippet is from a sidebar widget that lists "recent posts". Since its on the home page and I feature my lastest sticky post prominently on that page, I want to skip over the sticky in this loop. However, the post_not_in=sticky_posts has no effect.

<?php
    $the_query = new WP_Query("showposts=$number&offset=1&order=ASC&post_not_in=sticky_posts");

    while ($the_query->have_posts()) : $the_query->the_post();
        $do_not_duplicate = $post->ID; ?>
Was it helpful?

Solution

I took @tnorthcutt's answer from WordPress' Codex on query_posts() about Sticky Parameters and created a tandalone example you can drop as test.php into your website's root and see it run by navigating to a URL like this, with your domain substituted:

http://example.com/test.php

Some notes on the code; I had to use an array equivalent of the query string you passed to WP_Query() because the post__no_in argument can't be passed in as a comma delimited string (not sure why, probably an oversight?).

Also I wanted to make sure you know that starting with an offset=1 (instead of offset=0) means you'll be excluding the first post that otherwise would be returned by the query. Of course you'll still get the number of posts specified by $number assuming you have that many applicable posts +1. So here's the code:

<?php
header('Content-Type:text/plain');
include "wp-load.php";

$number = 5;

$the_query = new WP_Query(array(
  'showposts' => $number,
  'offset' => 1,  // This will cause the query to skip over first post
  'order' => 'ASC',
  'post__not_in' => get_option("sticky_posts"),
  ));
while ($the_query->have_posts()) : $the_query->the_post();
  the_title(); 
endwhile;

OTHER TIPS

If you want to exclude all sticky posts from a query, use

query_posts(array("post__not_in" =>get_option("sticky_posts")));

(from the codex)

Looks like that will only work on 3.0 or greater, though: http://wordpress.org/support/topic/excluding-sticky-posts-using-query_posts

Edit: in response to your comment below, try this (I'm not sure this will work, but hopefully it will get you started):

<?php 
$args=array(
    'showposts'=>'$number',
    'offset'=>'1',
    'order'=>'ASC',
    'post__not_in'=>get_option("sticky_posts")
    );
$the_query = new WP_Query($args);

    while ($the_query->have_posts()) : $the_query->the_post();

        $do_not_duplicate = $post->ID; ?>

Travis' answer is fine if you're building your own query, for a secondary loop perhaps, but if you need to modify your main blog query, you can use pre_get_posts to filter out the sticky posts.

In the example below, I'm only excluding the sticky posts if the query is the blog page, as I still want sticky posts to be returned on taxonomy and search pages etc (I'm displaying sticky posts as featured articles on the main news page).

add_action( 'pre_get_posts', 'custom_post_archive_changes' );
function custom_post_archive_changes( $query ) {
    if ( is_home() && $query->is_main_query() ) {

        // exclude sticky posts from main news page
        $stickies = get_option("sticky_posts");
        $query->set( 'post__not_in', $stickies );

    }
}

Just drop the snippet above in your functions.php file.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top