Как добавить уникальный фильтр на таксономии WordPress с примерами кода

В 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 и значительно улучшить удобство поиска контента на сайте.

Используйте данное руководство как шаблон для создания собственных решений и адаптируйте под специфику проекта.

⭐⭐⭐⭐⭐