Injecting content with $wp_query->current_post restarts from zero on paged pages. How to inject content after X posts, regardless of pagination?

For the record, I just found a new/different way to accomplish this goal. It’s not quite the same, but it does allow me to insert a new post type after every X posts in my original loop.

This is the source: https://www.gowp.com/blog/inserting-custom-posts-loop/

The method was done via the code below, which essentially injects a new custom post type into the loop, and it seems to work regardless of the pagination.

add_action( 'wp', 'fs_only_do_on_homepage' );
function fs_only_do_on_homepage() {

if( is_front_page() ) {

    /* change the query to inject ads after every X frequency */
    // https://www.gowp.com/blog/inserting-custom-posts-loop/

    add_filter( 'the_posts', 'fs_insert_ads', 10, 2 );
    function fs_insert_ads( $posts, $query ) {

        // We don't want our filter to affect post lists in the admin dashboard
        if ( is_admin() ) return $posts;

        // We also only want our filter to affect the main query
        if ( ! is_main_query() ) return $posts;

        // Set a variable for the frequency of the insertion which we'll use in some math later on
        $freq = 2;

        /* Retrieve the ads, and calculate the posts_per_page on the fly, 
         * based on the value from the original/main query AND our frequency
         * this helps ensure that the inserted posts stay in sync regardless of pagination settings
         */
        $args = array(
            'post_type'         => 'fs_ads',
            'posts_per_page'    => floor( $query->query_vars['posts_per_page'] / $freq ),
            'paged'             => ( $query->query_vars['paged'] ) ? $query->query_vars['paged'] : 1,
            'orderby'           => 'menu_order',
            'order'             => 'ASC',
            'meta_key'          => 'status',
            'meta_value'        => 'enable',
        );

        // inserts the ads into the $posts array, using array_slice() ... and do some math to ensure they are inserted correctly
        if ( $fs_ads = get_posts( $args ) ) {
            $insert = -1;
            foreach ( $fs_ads as $fs_ad ) {
                $insert =  $insert + ( $freq + 1 );
                array_splice( $posts, $insert, 0, array( $fs_ad ) );
            }
        }

        return $posts;
    } // end the fs_insert_ads function

} // end checking is_home

} // end the fs_only_do_on_homepage function

I do lose the ability to say which item goes between which post, but it does achieve my original goal of trying to inject a custom post type into my loop, after every X number of posts.

Leave a Comment