Last active
March 15, 2025 10:58
-
-
Save dkjensen/5190c554420ea2f19987a3f31ac95785 to your computer and use it in GitHub Desktop.
WordPress Gutenberg Query Loop View More AJAX
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Add data attributes to the query block to describe the block query. | |
* | |
* @param string $block_content Default query content. | |
* @param array $block Parsed block. | |
* @return string | |
*/ | |
function query_render_block( $block_content, $block ) { | |
global $wp_query; | |
if ( 'core/query' === $block['blockName'] ) { | |
$query_id = $block['attrs']['queryId']; | |
$container_end = strpos( $block_content, '>' ); | |
$inherit = $block['attrs']['query']['inherit'] ?? false; | |
// Account for inherited query loops | |
if ( $inherit && $wp_query && isset( $wp_query->query_vars ) && is_array( $wp_query->query_vars ) ) { | |
$block['attrs']['query'] = query_replace_vars( $wp_query->query_vars ); | |
} | |
$paged = absint( $_GET[ 'query-' . $query_id . '-page' ] ?? 1 ); | |
$block_content = substr_replace( $block_content, ' data-paged="' . esc_attr( $paged ) . '" data-attrs="' . esc_attr( json_encode( $block ) ) . '"', $container_end, 0 ); | |
} | |
return $block_content; | |
} | |
\add_filter( 'render_block', __NAMESPACE__ . '\query_render_block', 10, 2 ); | |
/** | |
* Replace the pagination block with a View More button. | |
* | |
* @param string $block_content Default pagination content. | |
* @param array $block Parsed block. | |
* @return string | |
*/ | |
function query_pagination_render_block( $block_content, $block ) { | |
if ( 'core/query-pagination' === $block['blockName'] ) { | |
$block_content = sprintf( '<a href="#" class="view-more-query button">%s</a>', esc_html__( 'View More' ) ); | |
} | |
return $block_content; | |
} | |
\add_filter( 'render_block', __NAMESPACE__ . '\query_pagination_render_block', 10, 2 ); | |
/** | |
* AJAX function render more posts. | |
* | |
* @return void | |
*/ | |
function query_pagination_render_more_query() { | |
$block = json_decode( stripslashes( $_GET['attrs'] ), true ); | |
$paged = absint( $_GET['paged'] ?? 1 ); | |
if ( $block ) { | |
$block['attrs']['query']['offset'] += $block['attrs']['query']['perPage'] * $paged; | |
\add_filter( 'query_loop_block_query_vars', function( $query ) { | |
// Only return published posts. | |
$query['post_status'] = 'publish'; | |
return $query; | |
} ); | |
echo render_block( $block ); | |
} | |
exit; | |
} | |
add_action( 'wp_ajax_query_render_more_pagination', __NAMESPACE__ . '\query_pagination_render_more_query' ); | |
add_action( 'wp_ajax_nopriv_query_render_more_pagination', __NAMESPACE__ . '\query_pagination_render_more_query' ); | |
/** | |
* Replace WP_Query vars format with block attributes format | |
* | |
* @param array $vars WP_Query vars. | |
* @return array | |
*/ | |
function query_replace_vars( $vars ) { | |
$updated_vars = [ | |
'postType' => $vars['post_type'] ?? 'post', | |
'perPage' => $vars['posts_per_page'] ?? get_option( 'posts_per_page', 10 ), | |
'pages' => $vars['pages'] ?? 0, | |
'offset' => 0, | |
'order' => $vars['order'] ?? 'DESC', | |
'orderBy' => $vars['order_by'] ?? '', | |
'author' => $vars['author'] ?? '', | |
'search' => $vars['search'] ?? '', | |
'exclude' => $vars['exclude'] ?? array(), | |
'sticky' => $vars['sticky'] ?? '', | |
'inherit' => false | |
]; | |
return $updated_vars; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( function( $ ) { | |
$( '.view-more-query' ).on( 'click', function( e ) { | |
e.preventDefault(); | |
const self = $( this ); | |
const queryEl = $( this ).closest( '.wp-block-query' ); | |
const postTemplateEl = queryEl.find( '.wp-block-post-template' ); | |
if ( queryEl.length && postTemplateEl.length ) { | |
const block = JSON.parse( queryEl.attr( 'data-attrs' ) ); | |
const maxPages = block.attrs.query.pages || 0; | |
$.ajax( { | |
url: i18n.ajax_url, | |
dataType: 'json html', | |
data: { | |
action: 'query_render_more_pagination', | |
attrs: queryEl.attr( 'data-attrs' ), | |
paged: queryEl.attr( 'data-paged' ), | |
}, | |
complete( xhr ) { | |
const nextPage = Number( queryEl.attr( 'data-paged' ) ) + 1; | |
if ( maxPages > 0 && nextPage >= maxPages ) { | |
self.remove(); | |
} | |
queryEl.attr( 'data-paged', nextPage ); | |
if ( xhr.responseJSON ) { | |
console.log( xhr.responseJSON ); // eslint-disable-line | |
} else { | |
const htmlEl = $( xhr.responseText ); | |
if ( htmlEl.length ) { | |
const html = htmlEl.find( '.wp-block-post-template' ).html() || ''; | |
if ( html.length ) { | |
postTemplateEl.append( html ); | |
return; | |
} | |
} | |
self.remove(); | |
} | |
}, | |
} ); | |
} | |
} ); | |
}( jQuery ) ); |
hannahmwool
commented
Oct 31, 2024
via email
Yes! I’ve used it many times for variations! I can share my code!
…On Thu, Oct 31, 2024 at 16:55 Laurel ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Curious if anyone has tried using this with a query block variation? I'm
attempting to and having trouble getting the load more to actually work.
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/dkjensen/5190c554420ea2f19987a3f31ac95785#gistcomment-5262584>
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA3YOLOTZDJJY3J3RCJMXCLZ6KKKPBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVEYTCMRTHA4TONZRU52HE2LHM5SXFJTDOJSWC5DF>
.
You are receiving this email because you commented on the thread.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>
.
@hannahmwool that would be great!
@dkjensen This is great work ... thanks ..
@dkjensen I am experiencing an issue with the "load more" button display after the last page appears. I also found that "'pages' => $vars['pages']" alias returns 0.
I try to set total no of page with the bellow code :
$paged = absint( $_GET[ 'query-' . $query_id . '-page' ] ?? 1 );
// Define query parameters (Get posts_per_page from the block settings)
$posts_per_page = $block['attrs']['query']['perPage'] ?? get_option('posts_per_page');
$args = array(
'post_type' => $block['attrs']['query']['postType'] ?? 'post',
'posts_per_page' => $posts_per_page,
'paged' => $paged,
);
// Run a new WP_Query to get total pages
$query = new WP_Query($args);
// Get total number of pages
$total_pages = $query->max_num_pages > 0 ? $query->max_num_pages : 1;
// Set the total number of pages in the query vars
$block['attrs']['query']['pages'] = $total_pages;
$block_content = substr_replace( $block_content, ' data-paged="' . esc_attr( $paged ) . '" data-attrs="' . esc_attr( json_encode( $block ) ) . '"', $container_end, 0 );`
Can you please suggest if the above code is correct or if there is a shorter form so that the pages return correctly?
thank you
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment