How To Make Sticky Posts Even Stickier In WordPress

Development News

As WordPress becomes more of a content management API and framework there are times when some of its legacy features are too mired in the context of “blog” to really be useful when it’s in use as a full content management system. Sticky posts are a great example. They only work on the index page (or custom blog page if you set your site up that way). ‘Stickiness’ isn’t just useful for the home page of a WordPress site but useful on individual category lists or archive pages, and even in the admin area.

If you want sticky posts to stick everywhere then adding the following code snippet to your functions.php file will work for you:

You can always add some extra conditional logic into the sticky_posts_query() function to restrict stickiness to the admin only, or to a certain category or archive. Go forth and play.

21 responses to “How To Make Sticky Posts Even Stickier In WordPress

  1. Hi All,
    Great post Robert! Thank for pointing me in the right direction.
    For those wanting to make this work in more recent WP versions, I’m running WP 4.5.2 and the following updates make it work:
    – First of all, change the menu order of the sticky posts from -1 to 1. The order is descending order so you want the 1’s first then the 0’s.
    – Second, update sticky_posts_query function to not check whether year isset because it’s always set and the $q is passed by reference, so no return needed and I’m using the updated set function to set the orderby:
    `function sticky_posts_query( $q ) {
    if ( ! is_admin() && ( ! isset( $q->query_vars[ ‘ignore_sticky_posts’ ] ) || ( isset( $q->query_vars[ ‘ignore_sticky_posts’ ] ) && ! $q->query_vars[ ‘ignore_sticky_posts’ ] ) ) && ! $q->query_vars[ ‘year’ ] && ! $q->query_vars[ ‘monthnum’ ] && ! $q->query_vars[ ‘day’ ] && ! isset( $q->query_vars[ ‘orderby’ ] ) ) {
    $q->set(‘orderby’, ‘menu_order date’);
    }
    }`
    Enjoy!

  2. Trisha
    Hi Robert – Glad I found this post but wondering if you’ve had a chance to look at updating this for current version of WP? I’m facing this problem of needing sticky posts on archive pages as well as CPT archives, but this code above is not working…..no errors, just doesn’t put the sticky posts at the top.

    Same here 🙁

  3. Hi Robert – Glad I found this post but wondering if you’ve had a chance to look at updating this for current version of WP? I’m facing this problem of needing sticky posts on archive pages as well as CPT archives, but this code above is not working…..no errors, just doesn’t put the sticky posts at the top.

    1. Hi Trisha, thanks for your comment. We haven’t tested this recently, so it may well need some updating. I’ll open a case for someone to look at it if we ever get some spare time, but as we’re fully booked with paid work I can’t promise it will be any time soon.

  4. Hi, I am assuming this code now no longer works on wordpress version 3.6+ – as added the code to functions.php, but the ordering of posts in categories with stickies is the same as before – no change.

    1. I’ve not tested it recently so it may need a refresh. Thanks for letting us know.

  5. Works great – but is there a way to make this work for custom post types? 🙂

    1. The filter doesn’t care what post type something is so it should work for custom ones too. Is that not the case for you?

      1. No, it only shows up in posts. Is there a way of register it in register_post_type?

        Thanks for the fast reply! 🙂

        1. Is your post type added by a plugin or is it code that’s part of your theme? Just wondering if there might be some code that’s setting the ‘orderby’ part of the query.

          1. It’s a part of my theme.
            Looks like this: http://codepad.org/8SNMxaSD

          2. Just tried with the “Custom Post Type UI” plugin and it still didn’t work :/

          3. I’ll do some more testing here and see if I can work it out. Might be worth putting a var_dump() or print_r() in the pre_get_posts filter t see if it’s actually running on your post type list. Sorry it’s not working for you :/

          4. Nothing happens :/

  6. one “}” missing to close the fix_sticky_posts function.

    I pasted the code as I wanted to make sure sticky posts are at the top of their own category page but it doesn’t work yet. Maybe it wasn’t the purpose. thx for your work though !

    1. Hey Anton,

      Thanks, there was a typo in the gist that I’ve fixed now. You should see the ordering take effect as soon as you’ve put the code in, and then made a post sticky/unsticky. Definitely should work on category pages etc… too.

  7. Great solution! I’ve run in to this problem of a number of occasions and haven’t this is by far the best way to solve it IMO.

    I noticed how ever that posts are still sticky (i.e. menu_order = -1) even after I make them un-sticky. To account for this I made a slight modification to you function, checking which posts are missing from the new list of sticky posts and resetting the menu_order of these posts.

    
    function fix_sticky_posts( $stickies ) {
        
        $old_stickies = array_diff(get_option( 'sticky_posts' ), $stickies);
        
    	foreach( $stickies as $sticky ) {
    		wp_update_post( array( 'ID' => $sticky, 'menu_order' => -1 ) );
    	}
    	
    	foreach ($old_stickies as $sticky) {
    		wp_update_post( array( 'ID' => $sticky, 'menu_order' => 0) );
    	}
    	
    	return $stickies;
    }
    add_filter('pre_update_option_sticky_posts', 'fix_sticky_posts');
    
    1. D’oh! Great catch – thought I’d tested that… oops :/

      I’ll update the code, thanks Simon.

  8. Where in functions.php?

    1. Anywhere really, for simplicities sake just paste it in at the bottom of the file before the ‘?>’

Leave a Reply

Your email address will not be published. Required fields are marked *