В WordPress таксономии — это мощный инструмент для организации контента по категориям, тегам и произвольным системам классификации. Однако стандартные виджеты и фильтры таксономий часто не удовлетворяют специфическим требованиям сайтов, особенно если нужна уникальная фильтрация с дополнительными условиями или удобным интерфейсом.
Почему важен уникальный фильтр для таксономий WordPress
Стандартные фильтры таксономий показывают все термины без сортировки или кастомизации, что не всегда удобно. Например, на сайте с большим количеством категорий или тегов пользователи могут запутаться и уйти, не найдя нужный контент. Уникальный фильтр позволяет:
- Визуально выделить важные термины;
- Фильтровать записи по сложным условиям, включая метаполя и пользовательские параметры;
- Улучшить UX за счёт AJAX-загрузки без перезагрузки страницы;
- Оптимизировать отображение и снизить нагрузку на сервер.
Рассмотрим пошагово, как создать такой фильтр самостоятельно.
Создание кастомного фильтра для таксономии с использованием WP_Query
Для начала создадим простой фильтр, который позволит выбрать термины таксономии и вывести записи по выбранному фильтру без перезагрузки страницы.
1. Регистрация таксономии (если нужно)
Если у вас нет своей таксономии, зарегистрируем её. Например, таксономия 'genre' для кастомного типа записи 'book':
function wpin_register_taxonomy_genre() {
register_taxonomy('genre', 'book', array(
'label' => 'Жанры',
'hierarchical' => true,
'public' => true,
'rewrite' => array('slug' => 'genre'),
));
}
add_action('init', 'wpin_register_taxonomy_genre');2. Добавление HTML фильтра на фронтенд
Создадим выпадающий список с терминами таксономии 'genre':
function wpin_display_genre_filter() {
$terms = get_terms(array(
'taxonomy' => 'genre',
'hide_empty' => true,
));
if (empty($terms) || is_wp_error($terms)) {
return;
}
echo '<select id="wpin-genre-filter" name="genre-filter">';
echo '<option value="">Выберите жанр</option>';
foreach ($terms as $term) {
echo '<option value="' . esc_attr($term->slug) . '">' . esc_html($term->name) . '</option>';
}
echo '</select>';
}
add_shortcode('wpin_genre_filter', 'wpin_display_genre_filter');Теперь добавьте шорткод [wpin_genre_filter] в нужное место страницы.
3. AJAX-запрос для подгрузки записей по фильтру
Чтобы при выборе жанра сразу показывались соответствующие записи без перезагрузки страницы, реализуем AJAX. Для этого добавим JavaScript и PHP обработчик.
function wpin_enqueue_scripts() {
wp_enqueue_script('wpin-filter-ajax', get_template_directory_uri() . '/js/wpin-filter.js', array('jquery'), null, true);
wp_localize_script('wpin-filter-ajax', 'wpin_ajax_params', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpin_filter_nonce'),
));
}
add_action('wp_enqueue_scripts', 'wpin_enqueue_scripts');Создайте файл wpin-filter.js в папке темы или плагина с таким содержимым:
jQuery(document).ready(function($) {
$('#wpin-genre-filter').on('change', function() {
var genre = $(this).val();
$.ajax({
url: wpin_ajax_params.ajax_url,
method: 'POST',
data: {
action: 'wpin_filter_books',
genre: genre,
nonce: wpin_ajax_params.nonce
},
success: function(response) {
if (response.success) {
$('#wpin-books-list').html(response.data);
} else {
$('#wpin-books-list').html('<p>Ничего не найдено</p>');
}
}
});
});
});4. Обработчик AJAX в PHP
function wpin_ajax_filter_books() {
check_ajax_referer('wpin_filter_nonce', 'nonce');
$genre = isset($_POST['genre']) ? sanitize_text_field($_POST['genre']) : '';
$args = array(
'post_type' => 'book',
'posts_per_page' => 10,
);
if ($genre) {
$args['tax_query'] = array(
array(
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => $genre,
),
);
}
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start();
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
wp_reset_postdata();
$output = ob_get_clean();
wp_send_json_success($output);
} else {
wp_send_json_error();
}
}
add_action('wp_ajax_wpin_filter_books', 'wpin_ajax_filter_books');
add_action('wp_ajax_nopriv_wpin_filter_books', 'wpin_ajax_filter_books');Расширение фильтра: добавление мета-поля и сортировки
Часто нужно фильтровать не только по таксономии, но и по метаполям, например, цене или рейтингу. Добавим поле для сортировки книг по рейтингу.
Добавление поля сортировки в HTML
function wpin_display_sort_filter() {
echo '<select id="wpin-sort-filter" name="sort-filter">';
echo '<option value="date">По дате</option>';
echo '<option value="rating">По рейтингу</option>';
echo '</select>';
}
add_shortcode('wpin_sort_filter', 'wpin_display_sort_filter');Обновление JS для передачи параметра сортировки
jQuery(document).ready(function($) {
function wpinLoadBooks() {
var genre = $('#wpin-genre-filter').val();
var sort = $('#wpin-sort-filter').val();
$.ajax({
url: wpin_ajax_params.ajax_url,
method: 'POST',
data: {
action: 'wpin_filter_books',
genre: genre,
sort: sort,
nonce: wpin_ajax_params.nonce
},
success: function(response) {
if (response.success) {
$('#wpin-books-list').html(response.data);
} else {
$('#wpin-books-list').html('<p>Ничего не найдено</p>');
}
}
});
}
$('#wpin-genre-filter, #wpin-sort-filter').on('change', wpinLoadBooks);
// Загрузка при инициализации
wpinLoadBooks();
});Обновление PHP обработчика для сортировки
function wpin_ajax_filter_books() {
check_ajax_referer('wpin_filter_nonce', 'nonce');
$genre = isset($_POST['genre']) ? sanitize_text_field($_POST['genre']) : '';
$sort = isset($_POST['sort']) ? sanitize_text_field($_POST['sort']) : 'date';
$args = array(
'post_type' => 'book',
'posts_per_page' => 10,
);
if ($genre) {
$args['tax_query'] = array(
array(
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => $genre,
),
);
}
if ($sort === 'rating') {
$args['meta_key'] = 'wpin_book_rating';
$args['orderby'] = 'meta_value_num';
$args['order'] = 'DESC';
} else {
$args['orderby'] = 'date';
$args['order'] = 'DESC';
}
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start();
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a>';
$rating = get_post_meta(get_the_ID(), 'wpin_book_rating', true);
if ($rating) {
echo ' — Рейтинг: ' . esc_html($rating);
}
echo '</li>';
}
echo '</ul>';
wp_reset_postdata();
$output = ob_get_clean();
wp_send_json_success($output);
} else {
wp_send_json_error();
}
}Использование плагинов WPShop для расширения функционала фильтрации
Если вы хотите получить готовое решение с более сложными фильтрами и настройками, обратите внимание на плагины из каталога WPShop, например, Clearfy Pro. Этот плагин позволяет оптимизировать и расширить стандартные возможности WordPress, включая работу с таксономиями и фильтрами.
Для создания визуально удобных фильтров также стоит рассмотреть интеграцию с WPCommunity, если у вас есть форум и нужно фильтровать темы по таксономиям.
Советы по оптимизации и безопасности фильтров таксономий
При создании кастомных фильтров важно учитывать нагрузку на сервер и безопасность:
- Используйте
wp_cacheдля кеширования результатов запросов, особенно при большом количестве записей. - Обязательно проверяйте nonce и права доступа в AJAX-обработчиках, чтобы избежать CSRF-атак.
- Минимизируйте количество выводимых записей на страницу и добавьте пагинацию, если данных много.
- Используйте
prepared statementsи функции WordPress API для безопасности SQL-запросов.
Эти меры обеспечат стабильную и быструю работу вашего фильтра.
Вывод
Создание уникального фильтра на таксономиях WordPress — задача вполне решаемая своими силами. Приведённые примеры показывают базовую реализацию с AJAX и возможностью расширения сортировкой и метаполями. В зависимости от задачи, вы можете дополнить фильтр дополнительными элементами, интегрировать с популярными плагинами из каталога WPShop и значительно улучшить удобство поиска контента на сайте.
Используйте данное руководство как шаблон для создания собственных решений и адаптируйте под специфику проекта.