How to Create a Load More Button using AJAX in WordPress without a Plugin

Are you looking for a way to enhance the user experience on your WordPress website and create a load more posts using AJAX in WordPress instead of traditional pagination? In this article, I will show you how to easily create a load more button using AJAX in WordPress without the need for a plugin. By following these steps, you can improve the browsing experience for your visitors and make your website more engaging.

The desired outcome of this tutorial is to create a load more button using AJAX in WordPress, allowing users to load additional posts without leaving the current page.

Please note: In this tutorial, I will be coding within a child theme to avoid breaking the main site. The theme used in this tutorial is GeneratePress.

Step 1: Creating a Page Template and Custom Query

Create a Page Template Called “template-testimonials.php”

  • Create a new file called “template-testimonials.php” in your child theme folder.
  • Add the necessary code to create the page template.
</php
/* Template Name: Testimonials */
/>

2. Copy and Modify the Code from the Original “page.php” File in the Main Theme:

  • Copy the code from the original “page.php” file in your main theme.
  • Paste the code into the “template-testimonials.php” file.
  • Customize the code to include the custom query for displaying testimonials.
<?php 

/* Template Name: Testimonials */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

get_header(); ?>

	<div <?php generate_do_attr( 'content' ); ?>>

    <main class="site-main" id="main">
      <article id="testimonials-archive-<?php the_ID(); ?>" <?php post_class(); ?>>
        <div class="inside-article">
          
          <div class="entry-header">
            <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
          </div>

          <div class="entry-content">
            <?php 
              /**
               * Animation & WOW Delay
               */
              $rzwn_data_wow_delay = false;
              $rzwn_data_wow_seconds = 0;

              /**
               * Create show more text variable
               */
              $show_more_text = esc_html__('Show More', 'rzwn-generatepress');

              /**
               * Paged
               *
               * Tell the WordPress exactly
               * what page is active.
               */
              if (get_query_var('paged')) {
                $paged = get_query_var('paged');
              } elseif (get_query_var('page')) {
                $paged = get_query_var('page');
              } else {
                $paged = 1;
              }

              // Show more ajax, excluded posts
              $exclude = isset($_GET['exclude']) ? $_GET['exclude'] : '';

              $args = array(
	              'post_type'		=> 'testimonial',
	              'paged' 			=> $paged,
              );
              
              if ($exclude) {
	              $args['post__not_in'] = $exclude;
              }

              $query = new WP_Query($args);

              if ($query->have_posts()) :
            ?>
              <div class="site-testimonials__ajax" data-entries-source="<?php echo md5('testimonials-loadmore'); ?>">
                <?php 
                  /**
                   * WOW Animation
                   */
                  $rzwn_data_wow_seconds == 12 ? $rzwn_data_wow_seconds = 0 : '';
                  $rzwn_wow_holder = "data-wow-delay=". $rzwn_data_wow_seconds/10 ."s";
                
                  while ( $query->have_posts() ) : $query->the_post(); ?>
                    <figure
                      id="card-id_<?php the_ID(); ?>" 
                      class="wp-block-image alignfull size-full image-card testimonial_card-loadmore"
                      data-entry-id="<?php the_ID(); ?>"
                    >
                      <div
                        class="image-card_inner wow fadeInUp"
                        <?php echo esc_attr($rzwn_data_wow_seconds ? $rzwn_wow_holder : ''); ?>
                      >
                        <?php 
                          $featured_img_url = get_the_post_thumbnail_url(get_the_ID(),'full');
                        ?>
                        
                        <img src="<?php echo esc_url($featured_img_url); ?>" alt="<?php echo the_title(); ?>" title="<?php echo the_title(); ?>">
                      </div>
                    </figure>
                <?php $rzwn_data_wow_seconds = $rzwn_data_wow_seconds + 2; endwhile; ?>
              </div>

              <?php 
                if ( $query->max_num_pages > $paged ) :
              ?>
                <div class="site-testimonials__ajax-pagination show-more__pagination text-center">
                  <a href="#" class="wp-element-button show-more__pagination-button" data-text="<?php echo esc_attr($show_more_text); ?>">
                    <?php echo esc_attr($show_more_text); ?>
                  </a>
                </div>
              <?php endif; ?>
            <?php endif; wp_reset_postdata(); ?>
          </div>

        </div>
      </article>
    </main>
	</div>

	<?php
	/**
	 * generate_after_primary_content_area hook.
	 *
	 * @since 2.0
	 */
	do_action( 'generate_after_primary_content_area' );

	generate_construct_sidebars();

	get_footer();

3. Create a Page Called “Testimonials” and Change the Page Template:

  • Create a new page in your WordPress admin panel called “Testimonials”.
  • In the “Page Attributes” section, select “Testimonials” as the page template.
create a load more posts using ajax in wordpress
create a load more posts using ajax in wordpress – create Testimonials Page

(Note: I will not be covering how to create a custom post type in this tutorial.)

Step 2: Registering JavaScript Libraries and Adding Custom Scripts

1. Copy and Paste the Code into Your “functions.php” File:

  • Add the provided code to your child theme’s “functions.php” file.
/* ======================================================================== */
/* Enqueue Custom JS Files */
/* ======================================================================== */
add_action( 'wp_enqueue_scripts', 'rzwn_enqueue_scripts', 50 );
function rzwn_enqueue_scripts(){

  if ( is_page_template( 'template-testimonials.php' ) ) {
    wp_enqueue_script(
      'WOW',
      'https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js',
      array(),
      null,
      true
    );

    wp_enqueue_script(
      'ImagesLoaded',
      'https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/5.0.0/imagesloaded.pkgd.min.js',
      array(),
      null,
      true
    );

    wp_enqueue_script(
      'isotope',
      '//unpkg.com/isotope-layout@3/dist/isotope.pkgd.js',
      array(),
      null,
      true
    );

    wp_enqueue_script(
      'packery',
      '//unpkg.com/isotope-packery@2/packery-mode.pkgd.js',
      array(),
      null,
      true
    );
    wp_enqueue_script(
      'rzwn-testimonial',
      get_stylesheet_directory_uri() . '/assets/js/testimonials-showmore.js',
      array('jquery'),
      1.0,
      true
    );
  }
}

2. Copy and Paste the Code into Your “testimonials-showmore.js” File:

  • Create a new file called “testimonials-showmore.js” and place it in the “/assets/js” directory.
  • Add the provided code to the file.
document.addEventListener("DOMContentLoaded", function() {
  (function($) {
    'use strict';

    $(window).on('load', function() {
      /**
       * Wow
       */
      var wow = new WOW();
      wow.init();

      /**
       * Masonry
       */
      var $masonry = $('.site-testimonials__ajax');


      function loadMorePost($button) {
        var this_wrapper 	= $button.parent().siblings('.site-testimonials__ajax');
        var loadMorePosts 	= $button.data("text");

        var data 		= {};
        data.exclude 	= [];

        var filteredItems = this_wrapper.isotope('getFilteredItemElements');
        if (filteredItems) {
          data.exclude = filteredItems.map(function(item) {
            return item.dataset.entryId;
          });
        }

        jQuery.ajax({
          type: 'GET',
          url: window.location.href,
          data: data,
          beforeSend: function() {
            $button.addClass('loading');
            $button.html('loading...').prop('disabled', true);
          },
          success: function(data) {
            $button.removeClass('loading');
            var $wrapperContainer = jQuery(data).find(
              '.site-testimonials__ajax[data-entries-source="' +
              this_wrapper.data('entries-source') +
              '"]'
            );
            
            var $data = $wrapperContainer.find(".testimonial_card-loadmore");
            
            var $hasMore = $wrapperContainer
              .siblings('.show-more__pagination')
              .find('.show-more__pagination-button').length;
            
            if ($data.length > 0) {
              $button.html(loadMorePosts).prop('disabled', true);

              this_wrapper.append($data);
              this_wrapper.isotope('appended', $data);

              this_wrapper.imagesLoaded().progress( function() {
                this_wrapper.isotope('layout');
              });

              wow.sync();
            }

            if (!$hasMore) {
              $button.parent().hide();
            }
          },
          error: function() {
            $button.html("No More Posts");
          }
        });
      }

      if ($masonry.length) {
        $masonry.isotope({
          'layoutMode': 'packery',
          'itemSelector' :'.testimonial_card-loadmore',
        });
      

        $(".show-more__pagination-button").on("click", function(e) {
          e.preventDefault();

          loadMorePost($(this));
        });

        window.dispatchEvent(new Event('resize'));
      }
    });
  })(jQuery);
});

Step 3: Styling Your New Custom Markup

1. Add the Styling Code to Your Child Theme’s “style.css” File:

  • Add the provided code to your child theme’s “style.css” file.
/* ------------------------------------------------------------------- 
 * ## Testimonials ajax
 * ------------------------------------------------------------------- */
/* .site-testimonials__ajax{
  position: relative;
} */

body .entry-content .alignfull.image-card{
  width: 100%;
  max-width: 100%;
  margin: 0 0 42px;
  height: initial;
  display: block;
  box-sizing: border-box;
}

@media only screen and (max-width: 578px){
	body .entry-content .alignfull.image-card{
		margin-bottom: 24px;
	}
}

.image-card *{
  box-sizing: border-box;
}

.image-card .image-card_inner{
  position: relative;
  padding: 12px;
  background-color: var(--base-2);
  border: 1px solid var(--base);
}
.image-card img{
  object-fit: cover;
  height: initial;
}

.text-center{
  text-align: center;
}

If everything is set up correctly, your website now has a load more functions on the Testimonials page. You can check out the demo here.

Conclusion

In conclusion, by following these simple steps, you can easily create a load more button using AJAX in WordPress without the need for a plugin. This will provide a better user experience for your visitors and enhance the overall usability of your WordPress website. Implementing this feature will allow users to load additional posts without leaving the current page, creating a smoother and more engaging browsing experience. Try it out and see the improvement in your website’s user experience.

Rizwan Aritonang

An independent WordPress & Front-End Developer from Bandung, Indonesia.

Get In Touch

Leave a Comment