Skip to content

Instantly share code, notes, and snippets.

@Bobz-zg
Last active February 26, 2022 00:41
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Bobz-zg/42337d22028230fe17ff03bd58824930 to your computer and use it in GitHub Desktop.
Save Bobz-zg/42337d22028230fe17ff03bd58824930 to your computer and use it in GitHub Desktop.
Filter WordPress posts by multiple custom taxonomy terms with AJAX Raw
<?php
/**
* AJAC filter posts by taxonomy term
*/
function vb_filter_posts_mt() {
if( !isset( $_POST['nonce'] ) || !wp_verify_nonce( $_POST['nonce'], 'bobz' ) )
die('Permission denied');
/**
* Default response
*/
$response = [
'status' => 500,
'message' => 'Something is wrong, please try again later ...',
'content' => false,
'found' => 0
];
$all = false;
$terms = $_POST['params']['terms'];
$page = intval($_POST['params']['page']);
$qty = intval($_POST['params']['qty']);
$pager = isset($_POST['pager']) ? $_POST['pager'] : 'pager';
$tax_qry = [];
$msg = '';
/**
* Check if term exists
*/
if (!is_array($terms)) :
$response = [
'status' => 501,
'message' => 'Term doesn\'t exist',
'content' => 0
];
die(json_encode($response));
else :
foreach ($terms as $tax => $slugs) :
if (in_array('all-terms', $slugs)) {
$all = true;
}
$tax_qry[] = [
'taxonomy' => $tax,
'field' => 'slug',
'terms' => $slugs,
];
endforeach;
endif;
/**
* Setup query
*/
$args = [
'paged' => $page,
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => $qty,
];
if ($tax_qry && !$all) :
$args['tax_query'] = $tax_qry;
endif;
$qry = new WP_Query($args);
ob_start();
if ($qry->have_posts()) :
while ($qry->have_posts()) : $qry->the_post(); ?>
<article class="loop-item">
<header>
<h2 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
</header>
<div class="entry-summary">
<?php the_excerpt(); ?>
</div>
</article>
<?php endwhile;
/**
* Pagination
*/
if ( $pager == 'pager' )
vb_mt_ajax_pager($qry,$page);
foreach ($tax_qry as $tax) :
$msg .= 'Displaying terms: ';
foreach ($tax['terms'] as $trm) :
$msg .= $trm . ', ';
endforeach;
$msg .= ' from taxonomy: ' . $tax['taxonomy'];
$msg .= '. Found: ' . $qry->found_posts . ' posts';
endforeach;
$response = [
'status' => 200,
'found' => $qry->found_posts,
'message' => $msg,
'method' => $pager,
'next' => $page + 1
];
else :
$response = [
'status' => 201,
'message' => 'No posts found',
'next' => 0
];
endif;
$response['content'] = ob_get_clean();
die(json_encode($response));
}
add_action('wp_ajax_do_filter_posts_mt', 'vb_filter_posts_mt');
add_action('wp_ajax_nopriv_do_filter_posts_mt', 'vb_filter_posts_mt');
/**
* Shortocde for displaying terms filter and results on page
*/
function vb_filter_posts_mt_sc($atts) {
$a = shortcode_atts( array(
'tax' => 'post_tag', // Taxonomy
'terms' => false, // Get specific taxonomy terms only
'active' => false, // Set active term by ID
'per_page' => 12, // How many posts per page,
'pager' => 'pager' // 'pager' to use numbered pagination || 'infscr' to use infinite scroll
), $atts );
$result = NULL;
$terms = get_terms($a['tax']);
if (count($terms)) :
ob_start(); ?>
<div id="container-async" data-paged="<?= $a['per_page']; ?>" class="sc-ajax-filter sc-ajax-filter-multi">
<ul class="nav-filter">
<li>
<a href="#" data-filter="<?= $terms[0]->taxonomy; ?>" data-term="all-terms" data-page="1">
Show All
</a>
</li>
<?php foreach ($terms as $term) : ?>
<li<?php if ($term->term_id == $a['active']) :?> class="active"<?php endif; ?>>
<a href="<?= get_term_link( $term, $term->taxonomy ); ?>" data-filter="<?= $term->taxonomy; ?>" data-term="<?= $term->slug; ?>" data-page="1">
<?= $term->name; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<div class="status"></div>
<div class="content"></div>
<?php if ( $a['pager'] == 'infscr' ) : ?>
<nav class="pagination infscr-pager">
<a href="#page-2" class="btn btn-primary">Load More</a>
</nav>
<?php endif; ?>
</div>
<?php $result = ob_get_clean();
endif;
return $result;
}
add_shortcode( 'ajax_filter_posts_mt', 'vb_filter_posts_mt_sc');
/**
* Pagination
*/
function vb_mt_ajax_pager( $query = null, $paged = 1 ) {
if (!$query)
return;
$paginate = paginate_links([
'base' => '%_%',
'type' => 'array',
'total' => $query->max_num_pages,
'format' => '#page=%#%',
'current' => max( 1, $paged ),
'prev_text' => 'Prev',
'next_text' => 'Next'
]);
if ($query->max_num_pages > 1) : ?>
<ul class="pagination">
<?php foreach ( $paginate as $page ) :?>
<li><?php echo $page; ?></li>
<?php endforeach; ?>
</ul>
<?php endif;
}
@tanmaypatel86
Copy link

Thank you for your message. I will try to fix it using console log.

I have used this below code for that,

msg = textStatus;
if (textStatus === 'success') {
    msg = data.responseJSON.found;
}
$status.text('Posts found: ' + msg);

@tanmaypatel86
Copy link

I have also fixed it the issue of "Posts found: undefined" (when I click on load more button again again and when I reach button like this "You reached the end"). Thank you so much for amazing coding.

@Bobz-zg
Copy link
Author

Bobz-zg commented Apr 7, 2020

@tanmaypatel86 glad to hear that, good work!

@tanmaypatel86
Copy link

Thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment