Foreach-generated custom tax queries, each with an ajax “Load more” button


I’m looping through custom taxonomy terms to create a WP_Query for each term, then displaying the posts on the front-end.

I’m also attempting to adapt this helpful tutorial(and accompanying comments) to add an ajax load more button to each loop iteration. This is what I believe distinguishes this issue from other posts on WP-StackExchange: adding a load more button to a looped query, rather than a single query or simply multiple hard-coded(non-looped) WP_Query’s on one page.

The original tutorial uses wp_localize_script to pass php data to a registered & enqueued jQuery script, but since I need unique variables created with each loop, it didn’t appear that I could use it(and the tutorial author himself says not to use wp_localize_script if using a custom WP_Query). The comments on that post also allude to the use of unique variables for multiple queries, but I couldn’t figure it out for looped queries.

The button that is included in each loop iteration:

// don't display the button if there are not enough posts
if (  $unique_query->max_num_pages > 1 )
    echo '<button class="load-more-btn">Load more</button>';

I realize that the following code is not as concise as it could be yet(hence why I’m here), but I’m including in each foreach’d query the same jQuery so I can create unique query vars for each loop (ie. current_page_<?php print $cat_string; ?>):

The jQuery included at the end of each loop iteration:

$cat_string = the current taxonomy term string – ie. los_angeles

var ajaxurl = "<?php print site_url() . '/wp-admin/admin-ajax.php'; ?>",
var posts_<?php print $cat_string; ?> = '<?php echo serialize( $unique_query->query_vars ) ?>',
current_page_<?php print $cat_string; ?> = <?php echo $unique_query->query_vars['paged'] ?>,
max_page_<?php print $cat_string; ?> = <?php echo $unique_query->max_num_pages ?>

        var button = $(this),
        data = {
            'action': 'loadmore',
            'query': posts_<?php print $cat_string; ?>,
            'page' : current_page_<?php print $cat_string; ?>

            url : ajaxurl, // AJAX handler
            data : data,
            type : 'POST',
            beforeSend : function ( xhr ) {
            success : function( data ){
                if( data ) { 
                    button.text( 'Load more' ).prev().before(data); // insert new posts
                    current_page_<?php print $cat_string; ?>++;

                    if ( current_page_<?php print $cat_string; ?> == max_page_<?php print $cat_string; ?> ) 
                        button.remove(); // if last page, remove the button
                } else {

                    /* This seems to be where it jumps currently when the button is clicked */

                    button.remove(); // if no data, remove the button as well

The ajax action loadmore is hooked in my functions.php like so:

function bos_loadmore_ajax_handler(){

    // prepare our arguments for the query
    $args = json_decode( stripslashes( $_POST['query'] ), true );
    $args['paged'] = $_POST['page'] + 1; // we need next page to be loaded
    $args['post_status'] = 'publish';

    // 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();

            get_template_part( 'template-parts/event', 'small' ); 


    die; // here we exit the script and even no wp_reset_query() required!

add_action('wp_ajax_loadmore', 'bos_loadmore_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_loadmore', 'bos_loadmore_ajax_handler'); // wp_ajax_nopriv_{action}

The unique query vars are instantiating and populating correctly—I can see the correct output for each tax term loop in the Inspector.

The “Load More” button is shown correctly since the query has 26 posts and is showing 20, but when I click the button it changes to “Loading…” then disappears. From some console.log‘s, it seems to jump right to the else branch for “no data found”, so I’m thinking the hooked action in my functions file isn’t getting the correct query vars to run the query. Does that seem correct?

I can’t figure out, though, how the query vars should be different to get the correct query.

And to be thorough, the WP_Query $args for each looped query are:

$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$args = array(
    'post_type'              => array( 'tribe_events' ),
    'post_status'            => array( 'publish' ),
    'posts_per_page'         => 20,
    'nopaging'               => false,
    'paged'                  => $paged,
    'tax_query'              => array(
            'taxonomy'         => 'tribe_events_cat',
            'field'            => 'name',
            'terms'            => $the_cat,

Any help is much appreciated.

, , , dmoz 2 years 2019-12-26T13:17:20-05:00 0 Answers 75 views 0

Leave an answer