Wordpress - Enable sticky posts to custom post_type

According to extensive and long running trac ticket #12702, custom post types don't (and likely won't) support sticky functionality.

It's probably not impossible to reuse it (with unholy amount of copy paste and edge cases) for CPT in custom site, but in my opinion custom solution (probably custom fields based) would be more practical and clean approach.


I've managed to get the following to work. Let me describe the technique so that you can decide whether or not to use it.

  1. the code uses two hooks, one fired just before the "side" meta boxes get placed, and another immediately after the "date/time" section in the publish meta box.

  2. the first hook (before) records the original post type, and then switches it to "post", wordpress thinks it's a post and sets the default fields specific to the "post" post type.

  3. the second hook (after) will reset the post type back to the original.

If anyone runs into any issues or can come up with any unforeseen use cases where this technique may fail, please do reply.

// see /wp-admin/edit-form-advanced.php .. since wp 2.5.0
add_action( 'submitpost_box', function() {
    // fyi .. unable to use "post_submitbox_minor_actions" action (/wp-admin/includes/meta-boxes.php) because $post_type is set early
    global $post;
    if ( isset( $post->post_type ) && in_array( $post->post_type, array( 'post_type_1', 'post_type_2' ) ) ) {
        echo 'before'; // debug
        $post->post_type_original = $post->post_type;
        $post->post_type = 'post';
    }
} );

// see /wp-admin/includes/meta-boxes.php .. since wp 2.9.0
add_action( 'post_submitbox_misc_actions', function() {
    global $post;
    if ( isset( $post->post_type_original ) && in_array( $post->post_type_original, array( 'post_type_1', 'post_type_2' ) ) ) {
        echo 'after'; // debug
        $post->post_type = $post->post_type_original;
        unset( $post->post_type_original );
    }
} );

Note: the above takes care of adding the option to the UI, you would still need to check-for and work-with sticky posts in you templates/output .. something like the following (just without the plugin):

https://wordpress.stackexchange.com/a/185915/466