php - Shortcode to pull posts

admin2025-06-06  3

I need some help please. I have created a shortcode to pull in posts, then using ajax it loads more posts. I have everything working but it is duplicating the first group of posts. below is my code.

This is the shortcode function:

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

    $showdate = $showauthor = $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,
        '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' ) * $init;

    $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="recent-posts-grid-container 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 );

                $seperator = ' | ';

                if($showdate || $showauthor) {

                    if($showauthor) {

                        $post_author = et_get_safe_localization( sprintf( __( '%1$s', 'et_builder' ), '<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>' ) );

                    }

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

                }

                foreach($cats as $cat) {
                    if($cat->term_id != 391)
                        $all_post_cats[] = 'cat-'.$cat->slug;
                }
                ?>
                <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
                    $count++;

                    unset($all_post_cats);
                ?>
            <?php endwhile;
            wp_reset_postdata(); ?>

            <?php
                if($trending) {

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

                }
            ?>
        </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-exclude="['.implode(',',$exclude_cats).']">More Stories</a></div>';
            endif;
        ?>

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

    }

}

This is the ajax call:

$('body .load-more-posts').on('click',function(e){
        e.preventDefault();

        var showauthor = $(this).data('showauthor');
        var showdate = $(this).data('showdate');
        var trending = $(this).data('trending');
        var exclude = $(this).data('exclude');

        // need this to determine when to hide the button
        var page_number_max = Math.ceil(myData.found_posts / myData.post_per_page);

        $.ajax({
            url : myData.ajaxurl, // AJAX handler
            data : {
                'action': 'loadmore', // the parameter for admin-ajax.php
                'query': myData.posts, // loop parameters passed by wp_localize_script()
                'cat' : myData.category,
                'page' : myData.current_page, // current page
                'posts_per_page' : myData.post_per_page,
                'showauthor' : showauthor,
                'showdate' : showdate,
                'trending' : trending,
                'exclude' : exclude,
            },
            type : 'POST',
            beforeSend : function ( xhr ) {
                $('.load-more-posts').text('Loading...'); // some type of preloader
            },
            success : function( data ){
                if( data ) {

                    $('.load-more-posts').text( 'More Stories' );
                    $('#main-posts').append(data); // insert new posts
                    myData.current_page++;

                    if ( myData.current_page == page_number_max ) 
                        $('.load-more-posts-btn-container').hide(); // if last page, HIDE the button

                } else {
                    $('.load-more-posts-btn-container').hide(); // if no data, HIDE the button as well
                }
            }
        });

        return false;

    });

And this is the call back function:

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 = $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'];

    $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' => $_POST['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 );

            $seperator = ' | ';

            if($showdate || $showauthor) {

                if($showauthor) {

                    $post_author = et_get_safe_localization( sprintf( __( '%1$s', 'et_builder' ), '<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>' ) );

                }

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

            }

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

            ?>

            <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 

        $count++;

        unset($all_post_cats);

        endwhile;

    endif;

    wp_reset_postdata();

    die;
}

I need some help please. I have created a shortcode to pull in posts, then using ajax it loads more posts. I have everything working but it is duplicating the first group of posts. below is my code.

This is the shortcode function:

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

    $showdate = $showauthor = $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,
        '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' ) * $init;

    $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="recent-posts-grid-container 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 );

                $seperator = ' | ';

                if($showdate || $showauthor) {

                    if($showauthor) {

                        $post_author = et_get_safe_localization( sprintf( __( '%1$s', 'et_builder' ), '<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>' ) );

                    }

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

                }

                foreach($cats as $cat) {
                    if($cat->term_id != 391)
                        $all_post_cats[] = 'cat-'.$cat->slug;
                }
                ?>
                <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
                    $count++;

                    unset($all_post_cats);
                ?>
            <?php endwhile;
            wp_reset_postdata(); ?>

            <?php
                if($trending) {

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

                }
            ?>
        </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-exclude="['.implode(',',$exclude_cats).']">More Stories</a></div>';
            endif;
        ?>

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

    }

}

This is the ajax call:

$('body .load-more-posts').on('click',function(e){
        e.preventDefault();

        var showauthor = $(this).data('showauthor');
        var showdate = $(this).data('showdate');
        var trending = $(this).data('trending');
        var exclude = $(this).data('exclude');

        // need this to determine when to hide the button
        var page_number_max = Math.ceil(myData.found_posts / myData.post_per_page);

        $.ajax({
            url : myData.ajaxurl, // AJAX handler
            data : {
                'action': 'loadmore', // the parameter for admin-ajax.php
                'query': myData.posts, // loop parameters passed by wp_localize_script()
                'cat' : myData.category,
                'page' : myData.current_page, // current page
                'posts_per_page' : myData.post_per_page,
                'showauthor' : showauthor,
                'showdate' : showdate,
                'trending' : trending,
                'exclude' : exclude,
            },
            type : 'POST',
            beforeSend : function ( xhr ) {
                $('.load-more-posts').text('Loading...'); // some type of preloader
            },
            success : function( data ){
                if( data ) {

                    $('.load-more-posts').text( 'More Stories' );
                    $('#main-posts').append(data); // insert new posts
                    myData.current_page++;

                    if ( myData.current_page == page_number_max ) 
                        $('.load-more-posts-btn-container').hide(); // if last page, HIDE the button

                } else {
                    $('.load-more-posts-btn-container').hide(); // if no data, HIDE the button as well
                }
            }
        });

        return false;

    });

And this is the call back function:

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 = $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'];

    $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' => $_POST['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 );

            $seperator = ' | ';

            if($showdate || $showauthor) {

                if($showauthor) {

                    $post_author = et_get_safe_localization( sprintf( __( '%1$s', 'et_builder' ), '<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>' ) );

                }

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

            }

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

            ?>

            <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 

        $count++;

        unset($all_post_cats);

        endwhile;

    endif;

    wp_reset_postdata();

    die;
}
Share Improve this question asked Nov 14, 2018 at 18:42 JasonJason 2052 silver badges12 bronze badges 2
  • This isn't a full working example, specifically in the articles_grid function, the variables $trending, $init, $offset, etc are all not defined. It's hard to help without a full example. – Matt Cromwell Commented Nov 15, 2018 at 3:41
  • 1 Hi Matt, it is a full working example. I actually figured out the issue just a little while ago. thank you though. – Jason Commented Nov 15, 2018 at 3:43
Add a comment  | 

1 Answer 1

Reset to default 1

UPDATE

Turns out the issue was with the first page of posts. I needed to account for page 1 when calling the ajax load more. Since this is a shortcode and not a template my query vars were not passing along to the ajax call. I resolved the issue by passing the page as a data attribute through the ajax call.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749180739a317037.html

最新回复(0)