I have a shortcode that gets posts. I am using the shortcode three times on the page. The first time I grab the first 6 posts, the second time I offset by 6 and grab the next 4 posts, the third time I offset by 10 and grab the next 8 but this time I have a load more button to keep adding 8 until all posts are showing.

When I hit the Load More button it duplicates that last two posts from the previous 8. So in this third section I have posts 1,2,3,4,5,6,7,8. When I hit the load more button I get 7,8,9,10,11,12,13,14

I have concluded that this has to do with the offset and my post per page. My post per page count is 8 but the query starts by offsetting 10.

If I change the offset to 8 I no longer have any duplicates.

below is my code:

add_shortcode( 'articles-grid', 'articles_grid' );
function articles_grid( $atts ) {

    $showdate = $showauthor = $showexcerpt = $post_excerpt = $post_meta = $post_author = $post_seperator = $post_published = $has_featured_article = $data_class = $results = $trend_class = '';

    extract( shortcode_atts( array (
        'offset'        => 0,
        'showdate'      => null,
        'trending'      => null,
        'category'      => null,
        'exclude'       => null,
        'showauthor'    => null,
        'showexcerpt'   => null,
        'init'          => 1
    ), $atts ) );

    $exclude_ids = array_map('intval', explode(',', $exclude));

    $exclude_featured = array(391);

    $exclude_cats = array_merge($exclude_featured,$exclude_ids);

    ob_start();

    if($trending) 
        $posts_per_page = 6;
    else
        $posts_per_page = get_option( 'posts_per_page' );

    $query = new WP_Query( array(
        'posts_per_page' => $posts_per_page,
        'offset' => $offset,
        'category__not_in' => $exclude_cats,
        'category__in' => $category,
        'orderby' => 'post_date',
        'order' => 'DESC',
        'post_type' => 'post',
        'post_status' => 'publish',
        'ignore_sticky_posts' => true,
    ) );

    if ( $query->have_posts() ) { 

        $published_posts = $query->found_posts;
        $page_number_max = ceil($published_posts / $posts_per_page);
    ?>
        <div id="main-posts" class="ajax_posts">
            <?php 
                $all_post_cats = array();
                $count = 1;
            ?>
            <?php while ( $query->have_posts() ) : $query->the_post(); ?>
                <?php
                $cats = get_the_category(get_the_ID());
                $thumb = get_the_post_thumbnail_url( get_the_ID(), 'full');

                $posted_time_diff = human_time_diff( get_the_time('U',get_the_ID()), current_time('timestamp') );

                $author_id = get_post_field ('post_author', get_the_ID());
                $author_name = get_the_author_meta( 'display_name', $author_id );

                $excerpt = get_the_excerpt(get_the_ID());

                $seperator = ' | ';

                if($showdate || $showauthor) {

                    if($showauthor) {

                        $story_author = get_field( "story_author", get_the_ID() );

                        if($story_author) {
                            $post_author = ' ' . esc_html__( '', 'et_builder' ) . 'By <span class="author">' . $story_author . '</span>';
                        } else {
                            $post_author = et_get_safe_localization( sprintf( __( '%1$s', 'et_builder' ), 'By <span class="author">' . esc_html( $author_name ) . ' </span>' ) );
                        }

                    }

                    if($showdate && $showauthor) {

                        $post_seperator = $seperator;

                    }

                    if($showdate) {

                        $post_published = et_get_safe_localization( sprintf( __( '%s', 'et_builder' ), '<span class="published">' . esc_html( $posted_time_diff ) . ' ago </span>' ) );

                    }

                    if($showexcerpt) {

                        $post_excerpt = et_get_safe_localization( sprintf( __( '%s', 'et_builder' ), '<p class="post-meta post-excerpt"><span class="excerpt">' . esc_html( $excerpt ) . '</span></p>' ) );

                    }

                    $post_meta = '<p class="post-meta">'.$post_author.$post_seperator.$post_published.'</p>'.$post_excerpt;

                }

                foreach($cats as $cat) {
                    if($cat->term_id != 391)
                        $all_post_cats[] = 'cat-'.$cat->slug;
                }

                if ($count % $posts_per_page == 1) {  
                    echo '<div id="" class="recent-posts-grid-container">';
                }
                ?>

                <article class="<?php echo $count; ?> recent-article <?php echo implode(' ',$all_post_cats); ?>">
                        <a href="<?php the_permalink(); ?>">
                            <div class="recent-post-featured-image-container">   
                                <div class="recent-post-featured-image" style="background-image: url(<?php echo $thumb; ?>)"></div> 
                            </div>
                            <div class="recent-post-content">
                                <div class="recent-post-title"><?php the_title(); ?></div>
                                <?php echo $post_meta; ?>
                            </div>
                        </a>
                </article>

                <?php

                if ($count % $posts_per_page == 0) {  
                    echo "</div>";
                }

                $count++;

                unset($all_post_cats);
                ?>

                <?php
                    if($trending) {

                        echo '<article class="trending-container '.$trend_class.'"><h2>Trending</h2>'.do_shortcode('[wpp cat="-394" range="last7days" limit=6 stats_views=1 order_by="views" excerpt_length=110 post_html=\'<li>{title}</li>\']').'</article>';

                    }
                ?>

            <?php endwhile;
            wp_reset_postdata(); ?>


        </div>

        <?php
            // don't display the button if there are not enough posts
            if (  $page_number_max > 1 ) :
                echo '<div class="load-more-posts-btn-container"><a href="#" class="load-more-posts" data-showauthor="'.$showauthor.'" data-showdate="'.$showdate.'" data-trending="'.$trending.'" data-showexcerpt="'.$showexcerpt.'" data-paged="'.$init.'" data-exclude="['.implode(',',$exclude_cats).']" data-ppp="'.$posts_per_page.'">More Stories</a></div>';
            endif;
        ?>

    <?php $myvariable = ob_get_clean();
        return $myvariable;

    }

}

This is the function called by ajax to load more:

add_action('wp_ajax_loadmore', 'categories_loadmore_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_loadmore', 'categories_loadmore_ajax_handler'); // wp_ajax_nopriv_{action}

function categories_loadmore_ajax_handler(){

    $showdate = $showauthor = $showexcerpt = $post_excerpt = $post_meta = $post_author = $post_seperator = $post_published = $has_featured_article = $data_class = $results = $trend_class = '';

    $showdate = $_POST['showdate'];
    $showauthor = $_POST['showauthor'];
    $trending = $_POST['trending'];
    $showexcerpt = $_POST['showexcerpt'];

    if(isset($_POST['posts_per_page']))

        $posts_per_page = $_POST['posts_per_page'];

    else {

        if($trending) 
            $posts_per_page = 9;
        else
            $posts_per_page = get_option( 'posts_per_page' );

    }

    $args = array(
        'cat' => $_POST['cat'],
        'category__not_in' => $_POST['exclude'],
        'paged' => $_POST['page'] + 1,
        'posts_per_page' => $posts_per_page,
        'post_status' => 'publish',
    );

    // it is always better to use WP_Query but not here
    query_posts( $args );

    if( have_posts() ) :

        $all_post_cats = array();
        $count = 1;

        // run the loop
        while( have_posts() ): the_post();

            // $trending= 1;
            // $showdate = 0;
            // $showauthor = 1;
            $cats = get_the_category(get_the_ID());
            $thumb = get_the_post_thumbnail_url( get_the_ID(), 'full');

            $posted_time_diff = human_time_diff( get_the_time('U',get_the_ID()), current_time('timestamp') );

            $author_id = get_post_field ('post_author', get_the_ID());
            $author_name = get_the_author_meta( 'display_name', $author_id );

            $excerpt = get_the_excerpt(get_the_ID());

            $seperator = ' | ';

            if($showdate || $showauthor) {

                if($showauthor) {

                    $story_author = get_field( "story_author", get_the_ID() );

                    if ( function_exists( 'coauthors_posts_links' ) ) {
                        $post_author = coauthors_posts_links($between = null, $betweenLast = "&nbsp;and&nbsp;", $before = "By&nbsp;", $after = null, $echo = false);
                    } else {
                        $post_author = et_get_safe_localization( sprintf( __( '%1$s', 'et_builder' ), 'By <span class="author">' . esc_html( $author_name ) . ' </span>' ) );
                    }

                }

                if($showdate && $showauthor) {

                    $post_seperator = $seperator;

                }

                if($showdate) {

                    $post_published = et_get_safe_localization( sprintf( __( '%s', 'et_builder' ), '<span class="published">' . esc_html( $posted_time_diff ) . ' ago </span>' ) );

                }

                if($showexcerpt) {

                    $post_excerpt = et_get_safe_localization( sprintf( __( '%s', 'et_builder' ), '<p class="post-meta post-excerpt"><span class="excerpt">' . esc_html( $excerpt ) . '</span></p>' ) );

                }

                $post_meta = '<p class="post-meta">'.$post_author.$post_seperator.$post_published.'</p>'.$post_excerpt;

            }

            foreach($cats as $cat) {
                if($cat->term_id != 391)
                    $all_post_cats[] = 'cat-'.$cat->slug;
            }

            if ($count % $posts_per_page == 1) {  
                echo '<div id="" class="recent-posts-grid-container">';
            }

            ?>

            <article class="<?php echo $count; ?> recent-article <?php echo implode(' ',$all_post_cats); ?>">
                    <a href="<?php the_permalink(); ?>">
                        <div class="recent-post-featured-image-container">   
                            <div class="recent-post-featured-image" style="background-image: url(<?php echo $thumb; ?>)"></div> 
                        </div>
                        <div class="recent-post-content">
                            <div class="recent-post-title"><?php the_title(); ?></div>
                            <?php echo $post_meta; ?>
                        </div>
                    </a>
            </article>

            <?php
                if($trending) {

                    echo '<article class="trending-container hide-trending"></article>';

                }
            ?>

            <?php 

            if ($count % $posts_per_page == 0) {  
                echo "</div>";
            }

        $count++;

        unset($all_post_cats);

        endwhile;

    endif;

    wp_reset_postdata();

    die; // here we exit the script and even no wp_reset_query() required!
}
  • And your question is...? As far as I understand, you've already solved your problem by setting offset to 8? – Krzysiek Dróżdż Nov 28 at 0:41
  • Read the first part. I can’t change the offset to be 8 because I am using the first 10 posts via the first and second function calls. If I use offset 8 then I would have a duplicate of posts 1,2 instead of 7,8 – Jason Nov 28 at 0:43
  • OK, but functions can have params and you can pass them as request data... – Krzysiek Dróżdż Nov 28 at 0:45
  • Yes as you can see in the second function I am already doing that – Jason Nov 28 at 0:47
  • 1
    Well... No, you don’t. You don’t set offset anywhere in your AJAX callback function... You set page and posts_per_page, so you ignore the count of posts that is already printed... – Krzysiek Dróżdż Nov 28 at 0:51

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.