0

Currently, my WordPress blog displays a list of latest posts on its homepage. They are ordered by date with the latest post being at the top of the list. Is there a filter or a function that I can add to Code Snippets plugin that would make one specific post sticky as number "four" in the list even when I publish new posts? It should look like this:

Blog homepage (Page 1)

  1. Post

  2. Post

  3. Post

  4. Specific post that is always sticky as number four in the list regardless of the publish date

Page 2

  1. Post

  2. Post

etc.

If it's important, I'm using free (not premium) GeneratePress theme.

1 Answer 1

0

We can make a specific post sticky as number four in the list with the help of custom query modification using a filter.

In the given code always_sticky_as_fourth_post function will check if the current query is the main query on the homepage.

Function merge_sticky_post will merges the specific sticky post into the main query results at the fourth position.

We need to add the given PHP code to the function.php file of the theme.

function always_sticky_as_fourth_post($query) {
    if ( $query->is_home() && $query->is_main_query() && !is_admin() ) {
        $sticky_post_id = 123; // Here we need to replace 123 with the ID of the post we want to make sticky.

        // Getting the current page number.
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

        // If we are on the first page, we need to modify the query to include the sticky post.
        if ($paged == 1) {
            // Ensure the post ID is excluded from the main query
            $query->set('post__not_in', array($sticky_post_id));

            // We can adjust the number of posts to display.
            $posts_per_page = $query->get('posts_per_page');
            $query->set( 'posts_per_page', $posts_per_page - 1 );

            // Here we are creating a new query to fetch the sticky post.
            add_action( 'pre_get_posts', function($sticky_query) use ( $sticky_post_id, $posts_per_page ) {
                if ( $sticky_query->is_home() && $sticky_query->is_main_query() && !is_admin() ) {
                    // We need to set up the sticky post query.
                    $sticky_query->set( 'post__in', array( $sticky_post_id ) );
                    $sticky_query->set( 'posts_per_page', 1 );
                    $sticky_query->set( 'orderby', 'none' );
                }
            });
        }
    }
}

add_action( 'pre_get_posts', 'always_sticky_as_fourth_post' );

// Here we are merging the results of the main query and the sticky post query.
function merge_sticky_post( $posts, $query ) {
    if ($query->is_home() && $query->is_main_query() && !is_admin()) {
        // Here we are getting the sticky post ID
        $sticky_post_id = 123; // We need to replace 123 with the ID of the post you want to make sticky.

        // Here we are checking if the sticky post is already in the list.
        $sticky_post_in_list = false;
        foreach ( $posts as $post ) {
            if ( $post->ID == $sticky_post_id ) {
                $sticky_post_in_list = true;
                break;
            }
        }

        // Here we are checking if the sticky post is not in the list, insert it at position 3 (index 3).
        if ( ! $sticky_post_in_list && ! empty( $posts ) ) {
            $sticky_post = get_post( $sticky_post_id );
            array_splice( $posts, 3, 0, array( $sticky_post ) );
        }
    }

    return $posts;
}

add_filter( 'the_posts', 'merge_sticky_post', 10, 2 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.