Skip to content

Instantly share code, notes, and snippets.

@BruceMcKinnon
Created June 10, 2020 01:51
Show Gist options
  • Save BruceMcKinnon/e8c59a8a2743291786eed559006888a4 to your computer and use it in GitHub Desktop.
Save BruceMcKinnon/e8c59a8a2743291786eed559006888a4 to your computer and use it in GitHub Desktop.
AJAX loading archives page
<?php
// AJAX load more button
// This button replaces the standard pagination code
if ( $wp_query->max_num_pages > 1 )
echo '<a class="button" id="load_more">Load More</a>';
?>
//
// All of this code thanks to https://rudrastyh.com/wordpress/load-more-posts-ajax.html
//
function posts_load_more_script() {
global $wp_query;
// register the js but do not enqueue it yet
wp_register_script( 'posts_load_more_js', get_stylesheet_directory_uri(). '/dist/assets/js/posts_load_more.js', array('jquery') );
// now the most interesting part
// we have to pass parameters to posts_load_more.js script but we can get the parameters values only in PHP
// you can define variables directly in your HTML but I decided that the most proper way is wp_localize_script()
wp_localize_script( 'posts_load_more_js', 'misha_loadmore_params', array(
'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $wp_query->query_vars ), // everything about your loop is here
'current_page' => get_query_var( 'paged' ) ? get_query_var('paged') : 1,
'max_page' => $wp_query->max_num_pages
) );
wp_enqueue_script( 'posts_load_more_js' );
}
add_action( 'wp_enqueue_scripts', 'posts_load_more_script' );
function misha_loadmore_ajax_handler(){
$limit = get_option('posts_per_page');
// prepare our arguments for the query
$args = json_decode( stripslashes( $_POST['query'] ), true );
//
// IMPORTANT - The initial oad of the news page shows 7 posts.
// Each time you click Load More, an additional 6 posts are loaded.
// This code handles that mis-match and adjusts the post offsets of the
// loop so that you don;t miss posts or duplicate them.
// Settings > Reading > Blog Posts = 6.
//
$args['paged'] = $_POST['page'] + 1; // we need next page to be loaded
$args['post_status'] = 'publish';
$args['posts_per_page'] = $limit;
$args['posts_per_archive_page'] = $limit;
$args['offset'] = ($limit+1) + (($_POST['page']-1) * $limit);
// it is always better to use WP_Query but not here
query_posts( $args );
if( have_posts() ) {
// run the loop
while( have_posts() ) {
the_post();
$post_format = get_post_format();
if ( ($post_format == '') && ( in_category( array("insights-news","legal-insight","news") ) ) ) {
$post_format = 'news-archive';
}
get_template_part( 'template-parts/content', $post_format );
}
}
die; // here we exit the script and even no wp_reset_query() required!
}
add_action('wp_ajax_loadmore', 'misha_loadmore_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_loadmore', 'misha_loadmore_ajax_handler'); // wp_ajax_nopriv_{action}
function ingeni_change_news_offset( $query ) {
$current_cat = $query->query["category_name"];
if ( in_array( $current_cat, array("insights-news","legal-insight","news") ) ) {
$limit = get_option('posts_per_page');
if ( !$_POST['page'] ) {
//
// Important - If this is the inial load of this page, then
// add one extra post onto the limit. Thus you have one hero post, plus
// the Settings > Reading > Blog Posts number of posts following
//
$limit += 1;
set_query_var('posts_per_archive_page', $limit);
set_query_var('posts_per_page', $limit);
}
}
}
add_action( 'pre_get_posts', 'ingeni_change_news_offset');
/*
This JS does the job of performing the AJAX load
*/
jQuery(function($){ // use jQuery code inside this to avoid "$ is not defined" error
jQuery('#load_more').click(function(){
var button = jQuery(this),
data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts, // that's how we get params from wp_localize_script() function
'page' : misha_loadmore_params.current_page
};
jQuery.ajax({ // you can also use $.post here
url : misha_loadmore_params.ajaxurl, // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.text('Loading...'); // change the button text, you can also add a preloader image
},
success : function( data ){
if( data ) {
//button.text( 'Load More' ).parent().parent().parent().prev().html(data); // insert new posts
jQuery("#news_content").append(data);
button.text( 'Load More' )
misha_loadmore_params.current_page++;
if ( misha_loadmore_params.current_page == misha_loadmore_params.max_page )
button.remove(); // if last page, remove the button
// you can also fire the "post-load" event here if you use a plugin that requires it
// jQuery( document.body ).trigger( 'post-load' );
} else {
button.remove(); // if no data, remove the button as well
}
}
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment