WordPress has post sticky option only for posts post type. So if you are going to create a new custom post type, there is no native way for adding support for sticky posts. This feature was considered to bring to the core, but didn’t happen sadly.
In my case, I’m using a plugin Sticky Custom Post Types to add sticky post support for my custom post type. But the problem is, the sticky posts doesn’t stick in the post type archive. If you are registering custom post type and want to display all posts from that custom post type in a page without using any page template, custom post type archive comes handy in this case. So, if you have a post type named place, WordPress will search for a page archive-place.php to display all the posts from place post type (if it supports archive. e.g: 'has_archive' => true).
But the problem arises here, you won’t see your sticky posts at the top of the post list. Because WordPress doesn’t process sticky posts on other pages except home (e.g: is_home()). So here’s the handy hack to move all the sticky posts to the top of the archive post list.
/**
* Put sticky posts to top at custom post archives
*
* WordPress doesn't do any processing for sticky posts in custom post type archives.
* It process sticky posts in homepage only (is_home()). This function processes
* sticky posts at custom post archive page and puts them to the top of list.
*
* @author Tareq Hasan (http://tareq.weDevs.com)
*
* @param array $posts array of queried posts
* @return array
*/
function wedevs_cpt_sticky_at_top( $posts ) {
// apply the magic on post archive only
if ( is_main_query() && is_post_type_archive() ) {
global $wp_query;
$sticky_posts = get_option( 'sticky_posts' );
$num_posts = count( $posts );
$sticky_offset = 0;
// loop through the post array and find the sticky post
for ($i = 0; $i < $num_posts; $i++) {
// Put sticky posts at the top of the posts array
if ( in_array( $posts[$i]->ID, $sticky_posts ) ) {
$sticky_post = $posts[$i];
// Remove sticky from current position
array_splice( $posts, $i, 1 );
// Move to front, after other stickies
array_splice( $posts, $sticky_offset, 0, array($sticky_post) );
$sticky_offset++;
// Remove post from sticky posts array
$offset = array_search($sticky_post->ID, $sticky_posts);
unset( $sticky_posts[$offset] );
}
}
// Fetch sticky posts that weren't in the query results
if ( !empty( $sticky_posts) ) {
$stickies = get_posts( array(
'post__in' => $sticky_posts,
'post_type' => $wp_query->query_vars['post_type'],
'post_status' => 'publish',
'nopaging' => true
) );
foreach ( $stickies as $sticky_post ) {
array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );
$sticky_offset++;
}
}
}
return $posts;
}
add_filter( 'the_posts', 'wedevs_cpt_sticky_at_top' );
So, grab the plugin mentioned earlier for adding sticky support to custom post type and use this code snippet to bring the sticky posts at the top.