Skip to content

Instantly share code, notes, and snippets.

@kbcarte
Last active May 5, 2023 17:09
Show Gist options
  • Save kbcarte/619dd225aeea78db3f7ef2df4c101771 to your computer and use it in GitHub Desktop.
Save kbcarte/619dd225aeea78db3f7ef2df4c101771 to your computer and use it in GitHub Desktop.
Page Template custom WP_Query with ajax and pagination
<?php
/*
Template Name: Blog Archive
Author: kbcarte
*/
get_header();
?>
<section class="article-list">
<div id="cat-list" class="cat-list">
<a data-topic="all" href="/blog/?topic=all" class="topic all current">All</a>
<a data-topic="cat-a" href="/blog/?topic=cat-a" class="topic cat-a">Topic A</a>
<a data-topic="cat-b" href="/blog/?topic=cat-b" class="topic cat-b">Topic B</a>
<a data-topic="cat-c" href="/blog/?topic=cat-c" class="topic cat-c">Topic C</a>
<a data-topic="cat-d" href="/blog/?topic=cat-d" class="topic cat-d">Topic D</a>
</div>
<div id="ajax-results"></div>
</section>
<script>
const clear_current_topics = (topic_links) => {
topic_links.forEach( (topic) => {
topic.classList.remove('current');
} );
}
const get_posts = (topic, paged) => {
jQuery.ajax({
type: 'POST',
url: '<?php echo admin_url("admin-ajax.php"); ?>',
data: {
action: 'blog_archive_ajax_pagination',
topic: topic,
paged: paged
},
success: function(data, textStatus, XMLHttpRequest){
jQuery("#ajax-results").html(data['data']['html']);
const current_topic = document.querySelector(".article-list .cat-list .topic.current").getAttribute('data-topic');
// another ajax call for when page numbers are clicked
const paged_nav_list = document.querySelectorAll("#ajax-results .pagination .page-numbers a.page-numbers");
if( paged_nav_list ){
paged_nav_list.forEach((p)=> {
const urlParams = new URLSearchParams(p.href.split('?')[1]);
// bug with pagination and `add_fragment` for the first page of pagination
if( p.text === "1" ){
p.href = "?paged=1&topic=" + current_topic;
}
p.addEventListener('click', (e) => {
e.preventDefault();
get_posts(urlParams.get('topic'), urlParams.get('paged'));
});
});
}
// another ajax call for when the category filter is clicked
const cat_nav_list = document.querySelectorAll(".article-list .cat-list .topic");
if( cat_nav_list ){
cat_nav_list.forEach((c)=> {
const urlParams = new URLSearchParams(c.href.split('?')[1]);
c.addEventListener('click', (e) => {
e.preventDefault();
clear_current_topics(cat_nav_list);
c.classList.add('current');
get_posts(urlParams.get('topic'), urlParams.get('paged'));
});
});
}
},
error: function(MLHttpRequest, textStatus, errorThrown){
console.log(errorThrown);
}
});
}
// get the list of posts initially on page load
get_posts('<?php echo $cat; ?>', '<?php echo $paged; ?>');
</script>
<?php
get_footer();
<?php
// Yoink: https://ourcodeworld.com/articles/read/1603/how-to-determine-the-estimated-reading-time-of-a-text-with-php
function estimateReadingTime($text, $wpm = 200) {
$totalWords = str_word_count(strip_tags($text));
$minutes = floor($totalWords / $wpm);
$seconds = floor($totalWords % $wpm / ($wpm / 60));
return "<span class='read-time'>" . $minutes . "</span>";
}
// Yoink https://wordpress.stackexchange.com/a/154364
if ( ! function_exists( 'pagination' ) ) {
function pagination( $paged = '', $max_page = '', $topic = 'all' ) {
$big = 999999999; // need an unlikely integer
if( ! $paged ) {
$paged = get_query_var('paged');
}
if( ! $max_page ) {
global $wp_query;
$max_page = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1;
}
echo paginate_links( array(
'base' => "%_%",
'current' => max( 1, $paged ),
'total' => $max_page,
'mid_size' => 1,
'prev_text' => __( '<span class="prev hide-me"></span>' ),
'next_text' => __( '<span class="next hide-me"></span>' ),
'type' => 'list',
'add_fragment' => "&topic=".$topic,
'format' => '?paged=%#%'
) );
}
}
function blog_archive_ajax_pagination(){
$paged = ($_POST['paged']) ? $_POST['paged'] : 1;
$temp = $posts;
$cat = $_POST['topic'];
if( !$cat ){
$cat = 'all';
}
if( $cat == 'all' ){
$main_args = array(
'post_status' => 'publish',
'posts_per_page' => 6,
'paged' => $paged
);
} else {
$main_args = array(
'post_status' => 'publish',
'posts_per_page' => 6,
'paged' => $paged,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $cat
)
)
);
}
$posts = new WP_Query( $main_args );
if( $posts->have_posts() ){
ob_start(); ?>
<div class="articles">
<?php
while( $posts->have_posts() ){
$posts->the_post();
?>
<div class="article">
<a href="<?php echo get_the_permalink( get_the_ID() ) ?>" class="featured-image" style="background-image: url(<?php echo get_the_post_thumbnail_url(get_the_ID()) ?>);"></a>
<div class="category"><?php echo get_the_category( get_the_ID() )[0]->name ?></div>
<h4 class="title"><?php echo get_the_title() ?></h4>
<div class="date-time"><?php echo date("M d, Y", strtotime(get_the_date())); ?> <span class="pipe">|</span> <?php echo estimateReadingTime(get_the_content()) ?> MIN READ</div>
<a href="<?php echo get_the_permalink( get_the_ID() ) ?>" class="read-more">Read More</a>
</div>
<?php
}
?>
</div>
<nav class="pagination">
<?php pagination( $paged, $posts->max_num_pages, $cat); ?>
</nav>
<?php
} else {
// Error message: sorry, no posts here
}
$posts = null;
$posts = $temp;
$response = array(
'status' => 'success',
'html' => ob_get_clean(),
'paged' => $paged
);
wp_reset_postdata();
wp_send_json_success($response);
wp_die();
}
add_action( 'wp_ajax_nopriv_blog_archive_ajax_pagination', 'blog_archive_ajax_pagination' );
add_action( 'wp_ajax_blog_archive_ajax_pagination', 'blog_archive_ajax_pagination' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment