Sticky Custom Post Types WordPress Plugin

2011-08-20 5:47pm by Ann

I needed sticky custom post types for a client project but found out that WordPress doesn’t support this out of the box. Luckily it turned out to be pretty simple to add in that functionality with just a little bit of code… which I have turned into a plugin for everyone to use! YAY!

Installation/instructions:

1. Download the plugin from wordpress.org.

2. Upload sticky-custom-post-types.php to the /wp-content/plugins/ directory.

3. Select custom post types you want to enable with the sticky function on the ‘Settings → Reading’ page. Unless you’re using custom queries to display your sticky posts, you probably also want to check the option to display selected post types on the blog home.

4. When adding/editing a custom post type, check the “Stick this to the front page” checkbox if you want to stick that custom post to the front page.

And that’s it!

Unfortunately there’s no way to put the “Stick this…” checkbox in the same place as it is on the built-in “Posts” add/edit page (to do so would require modifying core code), but I think that having it display immediately is actually a lot more straightforward than having to click through the visibility setting edit link to get to it.

24 Responses to “Sticky Custom Post Types WordPress Plugin”

  1. Ashu says:

    Hello,
    I have created 3 custom post types for my client, now my client want sticky post feature for the custom post type. He wants to show custom post type post by tags, categories and sticky. Am using custom query code to display the post list by categories and tags but not able to get this sticky feature. So can you please help me out with code.
    Any help much appreciated.
    Thanks a lot in advance,
    Ashu

  2. thomas says:

    Hi, this is a great plugin. One question how do I stop the custom post from also displaying in the loop? Im trying to use post__not_in but its not working
    code:
    $wp_query = new WP_Query();
    $wp_query->query( array( ‘post__not_in’ => get_option( ‘sticky_posts’ ) ));

    • Ann says:

      You need to set the ‘post_type’ argument to ‘post’ in your query. I just checked in a new version of the plugin that will optionally enable adding checked custom post types to the home loop (sticky posts are enabled only when is_home and on the first page) so please update and let me know if you’re still having problems.

  3. Tim says:

    Hi there,
    Plugin is great worked fine.. ..and then boom. An update to another plugin ‘Advanced Custom Fields’ (http://wordpress.org/extend/plugins/advanced-custom-fields/) has knocked it out and loops involving sticky posts dont work at all.

    Now I know that issues with other plugins isnt your responsibility and I dont mind, I just wondered if there was any obvious reasons as to why they dont play together..

    ..But anyhow, plugin on its own works fine!

    Thanks.

    • Ann says:

      I can’t think of why that plugin would affect mine… However I did recently update my plugin and by default it won’t include custom post types (sticky and normal) in the home loop anymore unless you enable that setting. Could that be your issue?

  4. Matt Jarvis says:

    Hi – thanks for this plug in, however with wordpress 3.1 and trying to list all posts in a custom post_type, it seems to interfere and bring in some very random results (not just stick posts). Was driving me a bit crazy as I couldn’t understand it, even using

    $show_query = new WP_Query( array (“post_type” => “sl_shows” , ‘ignore_sticky_posts’=> 1, ‘post_status’ => ‘publish’, ‘orderby’ => ‘title’, ‘order’ => ‘ASC’, ‘posts_per_page’ => 5 ) );

    brought in 2 other post_types (ignore_sticky_posts did seem to work, maybe there is some id overlap?)

    best wishes
    Matt

    • Ann says:

      Hey Matt, are you saying that your query is still bringing in random non-sticky posts of post types other than the one you specified? If so, are there any other filters that might be affecting query results? Did you try adding the suppress_filters parameter to your custom query?

  5. Vanessa says:

    Hi Ann, thanks for this plugin. Question: I created a custom post type and am displaying the posts via archive-posttype.php. It seems your plugin does not stick the posts in the archive page. Will your plugin work within an archive display? Thanks!

    • Ann says:

      Hi Vanessa, unfortunately the plugin doesn’t currently add sticky posts to the custom post type archive pages, although this function is something I would likely add down the line.

  6. Hi – nice plugin – works with the default WP frontpage default posts listing. Hoever I am having trouble getting it to work when I do a custom loop (of the Delight theme):

    $sticky = get_option('sticky_posts'); // my new code
    $args=array(
    'post__in' => $sticky, // my new code
    'ignore_sticky_posts' => 1, // my new code
    'gallery' => $cat_selected,
    'post_type' => 'portfolio',
    'posts_per_page' => $posts_per_page,
    'paged' => $paged
    );
    $my_query = null;
    $my_query = new WP_Query($args);
    $i=0; while ( $my_query->have_posts() ) : $my_query->the_post();

    any suggestions?
    many thanks,
    Mike

    • Ann says:

      If you look at wp-includes/query.php line 2683, you’ll see that all the logic for splicing sticky posts in at the top and removing them from the flow is only going to be run if is_home is true. So you could either set the home flag or copy the logic from the core to get your custom query to return the posts you’re looking for. Neither are really great solutions for sticky posts IMO, so perhaps the right thing to do would be to submit a suggestion to trac to expand on this limitation.

  7. Toine Kamps says:

    Hi Ann,

    Thanks for this plugin, I was looking for this!
    I was experiencing the same problems as Matt Jarvis, on a completely different page in a different loop suddenly other custom post types were showing up, even when post_type was set to ‘post’ like this:
    ‘post_type’ => ‘post’

    The suppress filters parameter in this loop did the trick though:
    ‘suppress_filters’ => true

    I discovered a second problem though if your’re using the very useful posts-to-posts plugin from scribu: http://scribu.net/wordpress/posts-to-posts

    If I want 2 out of my 6 custom post types to be enabled for sticky support on the homepage, I check these post types on the ‘Settings -> Reading’ page, as well as the ‘Display selected post type(s) on: home’.
    I discovered that the other 4 post types lose their connection from the posts-to-posts plugin if you do this, or at least they don’t show up anymore.

    If I check all 6 of the custom post types on the ‘Settings -> Reading’ page the problem is solved, but then anyone could make any of the custom posts sticky on the homepage. Is there are a fix for this?

    Thanks!

    • Ann says:

      Unfortunately I’m not familiar with that plugin… but I’m guessing that what you mean is that it’s already displaying custom post types you want on your home page, though not as sticky posts. Basically, I think the problem is that my plugin takes those backend settings and tells the home page to filter out all the custom post types that are unchecked… and it uses the same settings to determine which custom post types to add that sticky option checkbox to.

      To get around this, the easiest thing to do would probably be to disable my plugin’s home page posts filter and write your own. So in your functions.php file:


      function my_sticky_posts_filter($query) {
      if($query->is_home && !$query->get('suppress_filters')) {
      $post_types = get_post_types(array('_builtin' => false, 'public' => true), 'names');
      $query->set('post_type', $post_types);
      }
      return $query;
      }
      remove_filter('pre_get_posts', 'super_sticky_posts_filter');
      add_filter('pre_get_posts', 'my_sticky_posts_filter');

  8. Toine Kamps says:

    Thanks for you reply!
    Well, altough it’s a bit tricky that users can make any post type sticky now, I think I’ll stick to keeping the post_types checked for now.
    Setting that ‘suppress_filters’ is vital by the way, because it’s messing up almost all my other loops in my site.
    Cheers

  9. Igor says:

    Hello, Ann! Thank you for this clear plugin. I wonder if it’s possible or not, to get (with it’s help) a list of sticky posts of specific custom post type: not in the loop (where you can apply filter), but outside, for example in the sidebar.

    I use this common way:

    $sticky_ids = get_option(‘sticky_posts’);
    $sticky_posts = get_posts( ‘include’ => $sticky_ids )

    The problem is: there are ids of posts of all types, not only needed in every special case.

    • Ann says:

      Hi Igor,

      You should be able to specify the post types you want get_posts() to return. For example, say you just want to display two custom post types, “events” and “books”:


      $sticky_posts = get_posts(array(
      'post__in' => get_option('sticky_posts'),
      'post_type' => array('events', 'books')
      ));

  10. Antuan says:

    No funciona en WP 3.3.1

  11. Toine says:

    Hi again,
    Unfortunately your plugin is causing troubles with the plugin SlideDeck: http://www.slidedeck.com
    The slides are not showing up at all… I confirmed it’s caused by this plugin.
    Any ideas on how to fix this?
    Thanks!

  12. Toine says:

    To be more specific, it’s line 94 in your sticky-custom-post-types.php code:
    add_filter(‘pre_get_posts’, ‘super_sticky_posts_filter’);
    ‘pre_get_posts’ conflicts in someway….

    I really need both of these great plugins to work together :(

  13. Toine says:

    Hi Ann, thanks for getting back to me!
    Unfortunately that doesn’t change anything… It’s the following line:
    $query->set('post_type', $post_types);
    that messes everything up somehow (even my menus dissapear all of a sudden).
    How should my custom query look like when I remove your filter?
    Now it looks like this (it checks if there are any stickies otherwise it will show my latest post):

    $sticky = get_option(‘sticky_posts’); // Get sticky posts
    $tmp = array(‘post__in’ => $sticky, ‘post_status’ => ‘publish’); // Get published sticky posts
    $stickypublish = new WP_Query($tmp);
    $totalstickies = count($stickypublish); // Get total of published sticky posts

    $notsticky = get_posts(array(‘posts_per_page’ => 1)); // Get featured posts
    $total = count($notsticky); // Get total of featured posts

    if ($sticky) { // If there are sticky posts
    $supress = false;
    } else { // If there are no sticky posts
    $supress = true;
    }
    $args = array(
    'suppress_filters' => $supress,
    'posts_per_page' => 1,
    'post__in' => $sticky,
    'post_status' => 'publish',
    'ignore_sticky_posts' => 1
    );
    query_posts($args); // Show newest published sticky post

    if (have_posts()) :
    while (have_posts() ) : the_post(); ?>
    // Display post
    < ?php endwhile;
    endif;
    wp_reset_query(); ?>

    Any thoughts of what might go wrong?
    Thanks!

    • Ann says:

      Did you ever figure out these issues? Does the slidedeck plugin use custom post types for anything? Is something getting messed up on the blog home only or are other pages affected?

  14. Toine says:

    Hi Ann,
    Jup SlideDeck uses a custom post type for it’s slides, but almost al of the plugins do. Actually nothing got messed up, but the SlideDeck instances simply didn’t show up. In the end I think the problems were caused by the SlideDeck plugin itself.
    I ended up using a different plugin called ‘AnythingSlider’ http://wordpress.org/extend/plugins/anythingslider-for-wordpress/
    which works perfectly in combination with your plugin :)
    Thanks!

Leave a Reply