Issues with Sticky Post

Hi,
I am trying to create an Archive Layout for “News & Events” category, where

  • The latest sticky posts are shown on the Hero section
  • The next 3 sticky posts are shown on the subsequent row of 3 columns
  • All other posts are shown below

The problems I have encountered include:

  • Sticky posts are not detected. Sticky posts are not at the top. So posts are shown in chronological order.

The layout is a copy of the available Cornerstone Template.

If the sticky post is an issue, I’m happy to consider other approaches.

P.S. - I’ve tried creating a new and very basic Archive Layout with just a row and column. The post still doesn’t stick.

Thank you in advance.

QUICK UPDATE
I’ve written a small program to force stickies to be at the top.

function m3_sticky_posts_on_top_with_pagination( $query ) {
    // Ensure we target archive pages and the main query
    if ( $query->is_archive() && $query->is_main_query() ) {
        $sticky_posts = get_option( 'sticky_posts' );
        $posts_per_page = get_option( 'posts_per_page' );

        if ( ! empty( $sticky_posts ) ) {
            // Remove sticky posts from regular query results to prevent duplication
            $query->set( 'post__not_in', $sticky_posts );
            $query->set( 'ignore_sticky_posts', 1 ); 

            // Adjust pagination to include sticky posts
            $paged = max( 1, get_query_var( 'paged' ) );
            $offset = ( $paged - 1 ) * $posts_per_page;
            
            // Limit query to non-sticky posts for proper pagination
            $query->set( 'posts_per_page', $posts_per_page - count( $sticky_posts ) );
            $query->set( 'offset', $offset );

            // Prepend sticky posts manually and handle pagination
            add_filter( 'the_posts', function( $posts ) use ( $sticky_posts, $posts_per_page, $paged ) {
                $sticky_posts_array = get_posts( array(
                    'post__in' => $sticky_posts,
                    'post_type' => get_post_type(),
                    'post_status' => 'publish',
                    'orderby' => 'post_date',
                    'order' => 'DESC',
                    'ignore_sticky_posts' => 1
                ) );

                // Paginate sticky posts properly
                $sticky_chunk = array_slice( $sticky_posts_array, ( $paged - 1 ) * $posts_per_page, $posts_per_page );

                // Merge sticky and non-sticky posts while maintaining pagination
                return array_merge( $sticky_chunk, $posts );
            }, 10, 1 );
        } else {
            $query->set( 'posts_per_page', $posts_per_page );
        }
    }
}
add_action( 'pre_get_posts', 'm3_sticky_posts_on_top_with_pagination' );

Unfortunately, now the pagination doesn’t work. Help, please!

Got it fixed with this

function m3_sticky_posts_with_correct_pagination( $query ) {
    // Apply only to frontend, archive pages, and the main query
    if ( ! is_admin() && $query->is_archive() && $query->is_main_query() ) {
        // Get sticky posts and total posts per page
        $sticky_posts = get_option( 'sticky_posts' );
        $posts_per_page = get_option( 'posts_per_page' );

        if ( ! empty( $sticky_posts ) ) {
            // Ensure sticky posts are shown; prevent default sticky behavior
            $query->set( 'ignore_sticky_posts', 1 );
            $query->set( 'posts_per_page', $posts_per_page );

            // Modify query ordering for sticky posts
            add_filter( 'posts_clauses', function( $clauses, $query ) use ( $sticky_posts ) {
                global $wpdb;

                // Ensure this filter applies only to frontend archive queries
                if ( ! is_admin() && $query->is_archive() && $query->is_main_query() ) {
                    $sticky_post_sql = '(' . implode( ',', array_map( 'absint', $sticky_posts ) ) . ')';
                    $clauses['where'] .= " OR {$wpdb->posts}.ID IN {$sticky_post_sql} ";
                    $clauses['orderby'] = "{$wpdb->posts}.ID IN {$sticky_post_sql} DESC, " . $clauses['orderby'];
                }

                return $clauses;
            }, 10, 2 );
        }
    }
}
add_action( 'pre_get_posts', 'm3_sticky_posts_with_correct_pagination' );

Just sharing with others.

Thanks for sharing.