Adding Sticky functionality to Custom Post Type Archives

I think the answer to your questions lies on the following webpage.

Its author (Tareq Hasan) faced the same problem as we do and found a solution.

https://tareq.co/2013/01/sticky-posts-in-custom-post-type-archives/

Basically, you need to install the plugin you already have (Sticky Custom Post Types) and add a filter: (I paste the code here so if the page went down, we still have it.)

The plugin is quite old but is very simple in the way it works so it still works perfectly with WordPress 4.2. Same apply to the below code snippet.

Hope it helps you as it helped me.

/**
 * Put sticky posts to top at custom post archives
 * Author: Tareq Hasan
 * Source: http://tareq.wedevs.com/2013/01/sticky-posts-in-custom-post-type-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' );

Leave a Comment