0

Today I updated an old blog post and set it to sticky to show info about the latest changes. It’s a typical post with Site Updates as the title for a log of a sort you could say, with past changes listed by date.

What I discovered was if the post originates from page two or on, the sticky post still appears on page two or what ever page it came from however if the post originates on page one the post vanishes from the visible blog posts.

In my view a sticky post should only display as the sticky post, not twice in the blog for any reason.

If you have an explanation why this happens I'm keen to hear it.

Changing the number of posts per page shows me its related to whether a post is on page one or not and if it is and it’s a sticky, it disappears and only displays as a sticky however if it’s a sticky and from page two or on it remains visible on that page as well as a sticky on page one.

This seems like a bizarre function that’s worth fixing. I can’t see any reason a sticky post should appear twice in a blog, in fact it could potentially hurt SEO if its determined as duplicate content by search engines.

Interested in some input and if anything can be done to make sure a sticky post only shows as a sticky post and not elsewhere in the blog on another page at the same time.

1

Sticky posts are a pain in the butt, and is not properly implememnted IMHO. The source code clearly shows that sticky posts are only moved to the top on page one of the homepage (or any custom instance of WP_Query which emulates the homepage), sticky posts does not get removed from the paged pages. This, IMO, should be part of core, stickies should be moved to the top of page one and should be completely removed from the query after that.

As on the point of SEO, I'm not sure what the impact of this might be. SEO is a very advanced field that eludes me (and probably a lot of us on this stack). This might also be the wrong stack to ask such a question, I would think that the webmasters stack would be the best place to ask SEO related questions like this.

Anyways, to come back to the topic of stickies, what I always do is the following (Please follow the linked source code for better understanding):

  • Set ignore_sticky_posts to true on the home page via pre_get_posts. This will ignore the sticky posts function.

  • Still inside pre_get_posts, get the array of sticky posts and completely remove them from the query. This way, one do not have the headache of having to manually recalculate pagination due to offsets being used etc

  • Inject the sticky posts via the_posts filter into the main query's loop.

What is nice about doing it this way is,

  • sticky posts are not part of the main query anymore

  • saves on having to recaculate pagination if you are going to remove sticky posts only from page 2. I have done this before, but is a bit messy

Lets look at the code: (NOTE The code is untested an requires PHP 5.4+)

add_action( 'pre_get_posts', function ( $q )
{
    if (    $q->is_home()       // Only target the homepage
         && $q->is_main_query() // Only target the main query
    ) {
        // Remove sticky posts
        $q->set( 'ignore_sticky_posts', 1 );

        // Get the sticky posts array
        $stickies = get_option( 'sticky_posts' );

        // Make sure we have stickies before continuing, else, bail
        if ( !$stickies )
            return;

        // Great, we have stickies, lets continue
        // Lets remove the stickies from the main query
        $q->set( 'post__not_in', $stickies );

        // Lets add the stickies to page one via the_posts filter
        if ( $q->is_paged() )
            return;

        add_filter( 'the_posts', function ( $posts, $q ) use ( $stickies )
        {
            // Make sure we only target the main query
            if ( !$q->is_main_query() )
                return $posts;

            // Get the sticky posts
            $args = [
                'posts_per_page' => count( $stickies ),
                'post__in'       => $stickies
            ]; 
            $sticky_posts = get_posts( $args );

            // Lets add the sticky posts in front of our normal posts
            $posts = array_merge( $sticky_posts, $posts );

            return $posts;
        }, 10, 2 );
    }
});
  • yes I agree it can be a surprise to bump into a sticky post on a paged page. A little bit of Friday fun: Happy Stickies ;-) – birgire Apr 29 '16 at 9:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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