How to “Load More” posts via AJAX?

You can use ajax to load more posts on your archive page.

  1. attach a js/jquery click event on the More link
  2. send ajax request to admin-ajax.php (use wp_localize_script to get the ajax url to front end) with page number (track this with js variable).
  3. handle ajax request in php. Add custom ajax actions with add_action( 'wp_ajax_my_action', 'my_action' ); and add_action( 'wp_ajax_nopriv_my_action', 'my_action' ); (for non-logged in users). Send my_action part of the action hook as ajax request action parameter.
  4. query posts. Get the correct page (WP_Query paged arg, commented out in your code) for the query from the ajax request, e.g. $_POST['page']
  5. send queried posts back to front end
  6. append posts from ajax response to the dom with js/jquery.

I don’t think it matters that much if you use the default jQuery version or a newer one to load more posts.

Please have a look at the code examples here, https://www.billerickson.net/infinite-scroll-in-wordpress/ (not my blog), for more detailed example and explanation. I know code examples are preferred to links, but the code examples written by Bill Erickson are rather long so I think it is more to convenient post a link insted of copy-pasting the examples here.

You should also have a look at the codex entry about ajax, it is really helpfull. https://codex.wordpress.org/AJAX_in_Plugins

I only took a cursory glance at the query function you posted, but I think it should be fine for the post most part for loading more posts with ajax.


UPDATE 15.2.2019

If you need to identify which “Load more” link/button is clicked you can do this in js/jquery.

// Html
<div id="posts-cat-1" class="posts-section">
// posts here
<button id="cat-name-1" class="load-more">Load more</button>
</div>

<div id="posts-cat-2" class="posts-section">
// posts here
<button class="load-more" data-category="cat-name-2">Load more</button>
</div>

<div id="cat-name-3" class="posts-section">
// posts here
<button class="load-more">Load more</button>
</div>

// jQuery
jQuery('.load-more').on('click',function(event){
// get cat name from id
var catName1 = jQuery(this).attr('id');
// or from data attribute
var catName2 = jQuery(this).attr('data-category'); // or .data('category');
// or from parent section, perhaps not ideal
var catName3 = jQuery(this).closest('.posts-section').attr('id');

// Then pass the catName to your ajax request data so you can identify which category to query in php.
});

UPDATE 16.2.2019

To hide the “Load more” button when there are no more posts to show you can add a simple if-else conditional to your jquery ajax call.

// 2. Send to query function and get results
$.post(ajaxurl, data, function(response) {

  // Check if there's any content in the response.
  // I think your ajax php should return empty string when there's no posts to show
  if ( '' !== response ) {

    // Append the returned output to this selector
    $(response).appendTo('div#'+clicked_format).hide().fadeIn(2000); // was: $('div#'+clicked_format).append(response).fadeIn(4000); Reverse method, cf. https://stackoverflow.com/a/6534160/1375163

    // Change link text back to original
    $('a#'+clicked_format+' i').attr('class', 'fas fa-plus-circle'); // Icon
    $('a#'+clicked_format+' .moretext').text('More');                // Text

    // Increment "data-page" attribute of clicked link for next click
    // page++;
    $('a#'+clicked_format).find('span').data().page++

  } else {

    // This adds display:none to the button, use .remove() to remove the button completely
    $('a#'+clicked_format).hide();

  }

});

Leave a Comment