1

I want to create a load more function using ajax for a post category. I've followed this article on how to proceed, but after I add the function to register the endpoint, it will give me a 404 error about the second page that didn't exists.

Is there any error in the code or another way without using plugins to implement this in WP? (I'm an experienced PHP developer but I don't use wordpress a lot and it's all new for me for some aspects).

functions.php

    <?php
    add_action('rest_api_init', 'portfolio_ajax_api');
      function portfolio_ajax_api(){
        register_rest_route( 'portfolio', '/all-posts', array(
          'methods' => 'GET',
          'callback' => 'get_portfolio'
        ));
      }

  function get_showcase($request){
    $posts_data = array();
    $paged = $request->get_param('page');
    $paged = (isset($paged) || !(empty($paged))) ? $paged : 1;
    $posts = get_posts( array(
      'post_type'       => 'post',
      'status'          => 'published',
      'posts_per_page'  => 9,
      'orderby'         => 'post_date',
      'order'           => 'DESC',
      'paged'           => $paged
    ));

    foreach($posts as $post){
      $id = $post->ID;
      $post_thumbnail = (has_post_thumbnail($id)) ? get_the_post_thumbnail_url($id) : null;
      $post_cat = get_the_category($id);
      $featured = (get_field('project_featured', $id)) ? true : false;

      $posts_data[] = (object)array(
        'id' => $id,
        'slug' => $post->post_name,
        'type' => $post->post_type,
        'title' => $post->post_title,
        'featured_img_src' => $post_thumbnail,
        'featured' => $featured,
        'category' => $post_cat[0]->cat_name
      );
    }
    return $posts_data;
}
?>

template file:

<?php

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$portfolio = new WP_Query(array(
    'post_type'     => 'post',
    'status'        => 'published',
  'category_name' => 'portfolio',
    'posts_per_page'=> 1,
    'orderby'   => 'post_date',
    'order'         => 'DESC',
    'paged'         => $paged
));

?>

<div class="card-columns">
<?php if( $portfolio->have_posts() ): while( $portfolio->have_posts() ): $portfolio->the_post();  ?>
    <div class="card hide">
      <a href="<?php the_permalink(); ?>">
          <img class="card-img-top w-100" src="<?php the_post_thumbnail_url('full'); ?>" id="case-studies">
          <div class="overlay"><h4 class="text-center" id="client-name"><?php the_title(); ?></h4></div>
      </a>
    </div>
<?php endwhile; ?>
<?php endif; wp_reset_postdata(); ?>
</div>

<div class="row">
  <div class="col-sm-12 col-md-12 col-lg-12 text-center" id="show-more">
    <button class="btn btn-outline-dark" id="load-more"><?php _e('Visualizza altro') ?></button>
  </div>
</div>

main.js

    $('#load-more').on('click', function(e){
  e.preventDefault();
  var pull_page = 1;
  var jsonFlag = true;

  if(jsonFlag){
    pull_page++;

    $.getJSON("/u/wp-json/portfolio/all-posts?page=" + pull_page, function(data){
        if(data.length){
        pull_page++;

        console.log(data.length);

        $.each(data, function(i, item){
          var html = '<div class="card">';
          html += '<a href="'+ item.permalink +'">';
          html += '<img class="card-img-top w-100" src="'+ item.featured_img_src +'" id="case-studies" />';
          html += '<div class="overlay"><h4 class="text-center" id="client-name">'+ item.title +'</h4></div>';
          html += '</a>';
          html += '</div>';
          $('body').find('.card-columns')
          .append(html);
        });
      }
      else{
        jsonFlag = false;
      }
    }).done(function(data){
      if(data.length >= 4){
        jsonFlag = true;
      }
      else{
        jsonFlag = false;
      }
    });
    }

  }); // end load more

EDIT: I've solved the issue about the 404 error, It was due to the fact that wordpress is installed inside a subfolder of my local development server, so I've changed the url to match the correct route. Now the problem is that I need to display all posts with the $.each() loop inside a bootstrap card and I can't figure out how to proceed correctly. this because the html code for my cards is using the php wordpress loop generated by the wp_query on page load.

  • sounds like the parameter for paging $request->get_param('page') is not set properly? put it in your return and check, if its correct / hardcode another value just for testing.. – honk31 Feb 18 at 17:50
  • @honk31 I've solved, the url requested from getJSON() was wrong. The problem now I need to fix is how to show inside my bootstrap cards the json response. I want to use the $.each() function but with no success! – ZWPDev Feb 18 at 17:54
  • well, how does your response look like, whats the issue..? – honk31 Feb 18 at 18:02
  • the response log all the posts on page 2,3 ecc.. About the response part there is no problem, I have updated the code with the loop I'm using. The problem is on displaying all the items correctly – ZWPDev Feb 18 at 18:14
  • sorry, but its not clear, what the issue is. when you append val, than you have issues with the display? in what form? – honk31 Feb 19 at 8:56
1

I've solved the problem, I was made a mistake with the variable pull_page that is inside the click event. I've moved the variable outside the event and now all works fine. Here is the updated code!

var pull_page = 1;
var jsonFlag = true;

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

  if(jsonFlag){
    pull_page++;

    $.getJSON("/u/wp-json/portfolio/all-posts?page=" + pull_page, function(data){
        if(data.length){
        pull_page++;

        console.log(data.length);

        $.each(data, function(i, item){
          var html = '<div class="card">';
          html += '<a href="'+ item.permalink +'">';
          html += '<img class="card-img-top w-100" src="'+ item.featured_img_src +'" id="case-studies" />';
          html += '<div class="overlay"><h4 class="text-center" id="client-name">'+ item.title +'</h4></div>';
          html += '</a>';
          html += '</div>';
          $('body').find('.card-columns')
          .append(html);
        });
      }
      else{
        jsonFlag = false;
      }
    }).done(function(data){
      if(data.length >= 4){
        jsonFlag = true;
      }
      else{
        jsonFlag = false;
      }
    });
    }

  }); // end load more
  • ..told you so :) but what i see here is, that you increase pull_page twice..? looks wrong to me.. hopefully it works, as intended.. – honk31 Feb 26 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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