WordPress AJAX Taxonomy Filter
December 23, 2024 · AI Conversations
—
### **1. Register Taxonomy Filters**
Add dropdowns to filter posts based on the taxonomies. This code should be added to your theme’s template file where you want to display the filters (e.g., archive or a custom page template).
<?php
$taxonomy_1 = 'category'; // Replace with your taxonomy name
$taxonomy_2 = 'post_tag'; // Replace with another taxonomy name
$terms_1 = get_terms(['taxonomy' => $taxonomy_1, 'hide_empty' => true]);
$terms_2 = get_terms(['taxonomy' => $taxonomy_2, 'hide_empty' => true]);
?>
<div id="filters">
<select id="filter-taxonomy-1">
<option value="">Select Category</option>
<?php foreach ($terms_1 as $term): ?>
<option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
<select id="filter-taxonomy-2">
<option value="">Select Tag</option>
<?php foreach ($terms_2 as $term): ?>
<option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
</div>
<div id="posts-container">
<!-- AJAX posts will be rendered here -->
</div>
—
### **2. Enqueue Scripts**
Add the necessary JavaScript and pass AJAX URL to it.
function enqueue_taxonomy_filter_scripts() {
wp_enqueue_script('taxonomy-filter', get_template_directory_uri() . '/js/taxonomy-filter.js', ['jquery'], null, true);
wp_localize_script('taxonomy-filter', 'ajax_vars', ['ajax_url' => admin_url('admin-ajax.php')]);
}
add_action('wp_enqueue_scripts', 'enqueue_taxonomy_filter_scripts');
—
### **3. Create JavaScript File**
Create `taxonomy-filter.js` in your theme's `js` folder.
jQuery(document).ready(function ($) {
$('#filter-taxonomy-1, #filter-taxonomy-2').on('change', function () {
const taxonomy1 = $('#filter-taxonomy-1').val();
const taxonomy2 = $('#filter-taxonomy-2').val();
$.ajax({
url: ajax_vars.ajax_url,
type: 'POST',
data: {
action: 'filter_posts',
taxonomy_1: taxonomy1,
taxonomy_2: taxonomy2,
},
beforeSend: function () {
$('#posts-container').html('<p>Loading...</p>');
},
success: function (response) {
$('#posts-container').html(response);
},
});
});
});
—
### **4. Handle AJAX Request in PHP**
Add the following code to your theme's `functions.php`.
function filter_posts() {
$taxonomy_1 = sanitize_text_field($_POST['taxonomy_1']);
$taxonomy_2 = sanitize_text_field($_POST['taxonomy_2']);
$args = [
'post_type' => 'post',
'posts_per_page' => -1,
'tax_query' => [
'relation' => 'AND',
],
];
if (!empty($taxonomy_1)) {
$args['tax_query'][] = [
'taxonomy' => 'category', // Replace with your taxonomy name
'field' => 'slug',
'terms' => $taxonomy_1,
];
}
if (!empty($taxonomy_2)) {
$args['tax_query'][] = [
'taxonomy' => 'post_tag', // Replace with your taxonomy name
'field' => 'slug',
'terms' => $taxonomy_2,
];
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
?>
<div class="post-item">
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p><?php the_excerpt(); ?></p>
</div>
<?php
}
} else {
echo '<p>No posts found</p>';
}
wp_die();
}
add_action('wp_ajax_filter_posts', 'filter_posts');
add_action('wp_ajax_nopriv_filter_posts', 'filter_posts');
—
### **5. Add Styling (Optional)**
Style your dropdowns and posts container with CSS as needed.
—
### **Summary**
– Dropdowns will trigger an AJAX request on selection change.
– Posts will be filtered dynamically based on the selected taxonomy terms.
– AJAX requests will fetch and render posts without page reload.
Let me know if you need further assistance!
—
### **1. Update HTML for Dropdowns**
Add a class to each “ and include data attributes for taxonomy names.
<div id="filters">
<select class="taxonomy-filter" data-taxonomy="category">
<option value="">Select Category</option>
<?php foreach ($terms_1 as $term): ?>
<option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
<select class="taxonomy-filter" data-taxonomy="post_tag">
<option value="">Select Tag</option>
<?php foreach ($terms_2 as $term): ?>
<option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
</div>
<div id="posts-container">
<!-- AJAX posts will be rendered here -->
</div>
—
### **2. Update JavaScript**
Modify the JavaScript to send taxonomy names along with the selected slugs.
jQuery(document).ready(function ($) {
$('.taxonomy-filter').on('change', function () {
let filters = {};
// Loop through all dropdowns to collect data
$('.taxonomy-filter').each(function () {
const taxonomy = $(this).data('taxonomy');
const slug = $(this).val();
if (slug) {
filters[taxonomy] = slug;
}
});
$.ajax({
url: ajax_vars.ajax_url,
type: 'POST',
data: {
action: 'filter_posts',
filters: filters,
},
beforeSend: function () {
$('#posts-container').html('<p>Loading...</p>');
},
success: function (response) {
$('#posts-container').html(response);
},
});
});
});
—
### **3. Update PHP Handler**
Process the `filters` array to handle taxonomy names and slugs.
function filter_posts() {
$filters = isset($_POST['filters']) ? $_POST['filters'] : [];
$args = [
'post_type' => 'post',
'posts_per_page' => -1,
'tax_query' => ['relation' => 'AND'],
];
foreach ($filters as $taxonomy => $slug) {
$args['tax_query'][] = [
'taxonomy' => sanitize_text_field($taxonomy),
'field' => 'slug',
'terms' => sanitize_text_field($slug),
];
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
?>
<div class="post-item">
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p><?php the_excerpt(); ?></p>
</div>
<?php
}
} else {
echo '<p>No posts found</p>';
}
wp_die();
}
add_action('wp_ajax_filter_posts', 'filter_posts');
add_action('wp_ajax_nopriv_filter_posts', 'filter_posts');
—
### **Summary of Changes**
1. **HTML**: Added a class (`taxonomy-filter`) and data attributes (`data-taxonomy`) to the “ elements.
2. **JavaScript**: Collects taxonomy names and slugs dynamically from the dropdowns and sends them as an array.
3. **PHP**: Processes the `filters` array to construct the `tax_query` dynamically.
This setup ensures the dropdowns are classed, and the AJAX request sends both taxonomy names and their selected slugs for filtering. Let me know if you have further questions!