I am creating a shortcode that outputs a custom loop. Within the loop while, I am injecting certain content after a particular post count. This is done by checking the current_post number. This particular function is quite long (and filled with commented-out code, from testing).

Here is a link to my current version (currently with ALL posts on a single page): https://gist.github.com/Garconis/c93ce89c3d378bfb7f5d8df97acbebc2

This works fine if/when ALL posts (posts_per_page => -1) are showing, but as soon as I add pagination (e.g., set posts_per_page => 5, the injected content is starting from a count of 0 on each new page.

How can I update this, to be able to inject my specific content after X posts, without the count starting over with each new page?

Bare bones of what I have:

// create shortcode to list all Featured Itineraries
add_shortcode( 'fs_burn_homepage_loop','fs_all_featured_itineraries_shortcode' );
function fs_all_featured_itineraries_shortcode( $atts ) {
// Query posts from the database.
$options = array(
    // Arguments for your query.
    'post_type'         => array('post', 'ajde_events'),
    'posts_per_page'    => 5,
    'paged'             => 1,

/* To get the Easy Load More plugin to work */
if ( get_query_var( 'paged' ) ) { 
    $options['paged'] = get_query_var( 'paged' ); 
elseif ( get_query_var( 'page' ) ) { 
    $options['paged'] = get_query_var( 'page' ); 
} else { 
    $options['paged'] = 1; 

$query = new WP_Query( $options );
// Check that we have query results
if ( $query->have_posts() ) {

    // we have posts, so lets wrap them
    echo'<div id="fs-homepage-loop" class="fs-all-posts">';

        // Start looping over the query results.
        while ( $query->have_posts() ) {

            // Set up post data.

            echo '<article id="post-'. get_the_ID() .'" class="fs-post-article '. join( ' ', get_post_class() ) .'">
                <div class="fs-post-content-wrapper">
                    <div class="fs-post-name">
                        <h2 class="entry-title"><a href="'. get_permalink(); .'">'. get_the_title() .'</a></h2>

            // inject stuff after X posts
            if( ($query->current_post == 3) ) {
                echo '<article class="fs-post-article">
                    <div class="fs-post-content-wrapper">
                        content after post 4 is here
            if( ($query->current_post == 9) ) {
                echo '<article class="fs-post-article">
                    <div class="fs-post-content-wrapper">
                        content after post 10 is here

        // close the loop WHILE


    // close post wrapper
    echo '</div>';

    //function for the Easy Load More plugin

    $myvariable = ob_get_clean();

    return $myvariable;

// close the query IF
// ELSE it cant find ANY posts that match
else {
    echo '<div class="fs-no-posts-found"><h4>We currently have no stories to show you.</h4></div>';
// close the query ELSE */

Would it be as simple as somehow checking the current_post count AND the page number of the pagination? Since I supposedly know how many posts would show per page...

1 Answer 1


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.

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.