В WordPress часто возникает задача — сделать удобный и гибкий выбор записей по таксономиям, которые могут меняться динамически. Например, когда категории или метки добавляются и изменяются администратором, и фильтр должен автоматически подстраиваться под эти изменения. В этой статье мы подробно рассмотрим, как создать такой выбор по динамическим таксономиям с помощью PHP, WP_Query и AJAX, чтобы улучшить UX на сайте и сделать фильтрацию максимально удобной.
Что такое динамические таксономии и зачем их фильтровать?
Таксономии в WordPress — это способ группировки записей. Стандартные таксономии — категории и метки, но можно создавать собственные (Custom Taxonomies). Динамическая таксономия — это та, содержимое которой меняется постоянно: появляются новые термины, удаляются старые, изменяется иерархия. Если фильтр на сайте сделан статичным, он не будет отражать эти изменения, что ухудшает удобство пользователя.
Поэтому логично создавать фильтры, которые подгружают актуальный список терминов таксономии и формируют запросы с учетом выбранных значений.
Пример использования динамических таксономий
Представим, что на сайте есть таксономия product_brand, в которой администратор добавляет бренды товаров. Чтобы пользователь мог выбрать товары определенного бренда, нужно вывести список брендов, который обновляется автоматически.
Как получить список терминов таксономии программно
Для начала нам необходимо вывести список терминов таксономии, например, product_brand. Для этого используем функцию wp_team_get_dynamic_terms():
function wp_team_get_dynamic_terms($taxonomy) {
return get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
}Эта функция возвращает массив объектов терминов, включая пустые. Если нужно показывать только те термины, которые связаны с записями — ставим 'hide_empty' => true.
Вывод формы выбора таксономий с AJAX для динамического обновления
Для комфортного выбора сделаем форму с выпадающим списком и динамическим обновлением результатов без перезагрузки страницы.
HTML и JavaScript для выбора таксономии
Пример HTML и JS, который подгружает термины и отправляет AJAX запрос на сервер для получения отфильтрованных записей:
<select id="wp_team_taxonomy_filter">
<option value="">Выберите бренд</option>
</select>
<div id="wp_team_results"></div>
<script>
function wp_team_load_terms() {
fetch('/wp-json/wp/v2/product_brand') // или AJAX с admin-ajax.php
.then(response => response.json())
.then(data => {
const select = document.getElementById('wp_team_taxonomy_filter');
data.forEach(term => {
const option = document.createElement('option');
option.value = term.id;
option.textContent = term.name;
select.appendChild(option);
});
});
}
function wp_team_filter_posts() {
const select = document.getElementById('wp_team_taxonomy_filter');
const termId = select.value;
fetch(`/wp-json/wp-team/v1/filter-posts?brand_id=${termId}`)
.then(response => response.json())
.then(posts => {
const container = document.getElementById('wp_team_results');
container.innerHTML = '';
if(posts.length === 0) {
container.textContent = 'Ничего не найдено';
return;
}
posts.forEach(post => {
const div = document.createElement('div');
div.innerHTML = `<h3>${post.title.rendered}</h3><p>${post.excerpt.rendered}</p>`;
container.appendChild(div);
});
});
}
document.getElementById('wp_team_taxonomy_filter').addEventListener('change', wp_team_filter_posts);
window.addEventListener('DOMContentLoaded', wp_team_load_terms);
</script>Здесь мы используем REST API WordPress. Для кастомной фильтрации создадим собственный эндпоинт.
Создание REST API эндпоинта для фильтрации записей по таксономии
Добавим код в functions.php или в свой плагин для регистрации маршрута и обработки запроса:
add_action('rest_api_init', function() {
register_rest_route('wp-team/v1', '/filter-posts', [
'methods' => 'GET',
'callback' => 'wp_team_filter_posts_by_brand',
'permission_callback' => '__return_true',
]);
});
function wp_team_filter_posts_by_brand(WP_REST_Request $request) {
$brand_id = $request->get_param('brand_id');
$args = [
'post_type' => 'product',
'posts_per_page' => 10,
];
if($brand_id) {
$args['tax_query'] = [
[
'taxonomy' => 'product_brand',
'field' => 'term_id',
'terms' => intval($brand_id),
]
];
}
$query = new WP_Query($args);
$posts = [];
if($query->have_posts()) {
while($query->have_posts()) {
$query->the_post();
$posts[] = [
'id' => get_the_ID(),
'title' => ['rendered' => get_the_title()],
'excerpt' => ['rendered' => get_the_excerpt()],
];
}
wp_reset_postdata();
}
return $posts;
}Этот код позволяет получить список записей типа product с фильтрацией по бренду. Если бренд не выбран, возвращаются все записи.
Советы по улучшению фильтрации и UX
Множественный выбор терминов
Можно расширить фильтр так, чтобы пользователь выбирал несколько терминов. Для этого меняем select на multiple и передаем массив ID терминов в REST API запросе. На сервере меняем параметр 'terms' на массив.
Кеширование результатов
Чтобы снизить нагрузку, используйте Transients API или объектный кеш для хранения результатов запросов с одинаковыми параметрами на короткое время.
Интеграция с плагинами
Если используете плагин Clearfy Pro, он помогает оптимизировать REST API и убрать избыточные данные, что ускорит отклик фильтра.
Вывод
Создание выбора по динамическим таксономиям в WordPress — это несложная, но важная задача для сайтов с большим и часто меняющимся контентом. Использование REST API и AJAX делает фильтрацию быстрой и удобной для пользователей, а применение Transients и оптимизаций поможет снизить нагрузку на сервер.
Такой подход позволит создавать гибкие и масштабируемые фильтры, которые легко поддерживать и расширять в будущем.