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

В этой статье рассмотрим, как создать уникальный и гибкий фильтрованный список постов в WordPress. Мы разберём, как построить кастомный WP_Query с несколькими параметрами, как добавить AJAX-подгрузку, чтобы улучшить взаимодействие пользователя, и приведём примеры кода для быстрой интеграции.

Понимание WP_Query и фильтрация по метаданным и таксономиям

Для начала важно понять, что WP_Query — это мощный класс WordPress, который позволяет получать записи из базы данных с учётом различных параметров. Вы можете фильтровать посты по категориям, меткам, произвольным таксономиям, пользовательским полям (custom fields) и другим критериям.

Допустим, нам нужно вывести записи определённого типа с фильтрацией по нескольким таксономиям и пользовательским полям. Для этого используем параметры tax_query и meta_query.

Пример базового запроса с фильтрацией по категории и произвольному полю:

$args = [
    'post_type' => 'post',
    'tax_query' => [
        [
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => 'novosti',
        ],
    ],
    'meta_query' => [
        [
            'key'     => 'author_rating',
            'value'   => 4,
            'compare' => '>=',
            'type'    => 'NUMERIC',
        ],
    ],
];
$query = new WP_Query($args);

Здесь мы получаем посты из категории «novosti», у которых значение метаполя author_rating не меньше 4.

Создание формы фильтрации и обработка пользовательского ввода

Чтобы пользователи могли выбирать параметры фильтра, создадим HTML-форму с нужными полями. Например, выпадающий список категорий и радиокнопки для рейтинга:

<form id="filter-form">
    <select name="category" id="filter-category">
        <option value="">Все категории</option>
        <option value="novosti">Новости</option>
        <option value="stati">Статьи</option>
    </select>
    <label>
        <input type="radio" name="rating" value="3"> От 3
    </label>
    <label>
        <input type="radio" name="rating" value="4"> От 4
    </label>
    <button type="submit">Применить</button>
</form>
<div id="posts-container"></div>

Форма отправляет данные на сервер, и мы обновляем список постов динамически с помощью AJAX.

Реализация AJAX-подгрузки фильтрованных постов

Добавим JavaScript для перехвата отправки формы и выполнения AJAX-запроса:

jQuery(document).ready(function($) {
    $('#filter-form').on('submit', function(e) {
        e.preventDefault();

        var data = {
            action: '2wp_filter_posts',
            category: $('#filter-category').val(),
            rating: $('input[name="rating"]:checked').val(),
            nonce: filter_vars.nonce
        };

        $.post(filter_vars.ajaxurl, data, function(response) {
            $('#posts-container').html(response);
        });
    });
});

Теперь создадим PHP-функцию для обработки AJAX-запроса. В functions.php темы или в плагине добавим:

add_action('wp_ajax_2wp_filter_posts', 'twop_ru_filter_posts_callback');
add_action('wp_ajax_nopriv_2wp_filter_posts', 'twop_ru_filter_posts_callback');

function twop_ru_filter_posts_callback() {
    check_ajax_referer('2wp_filter_nonce', 'nonce');

    $category = sanitize_text_field($_POST['category'] ?? '');
    $rating = intval($_POST['rating'] ?? 0);

    $args = [
        'post_type' => 'post',
        'posts_per_page' => 10,
    ];

    if ($category) {
        $args['tax_query'] = [[
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => $category,
        ]];
    }

    if ($rating > 0) {
        $args['meta_query'] = [[
            'key' => 'author_rating',
            'value' => $rating,
            'compare' => '>=',
            'type' => 'NUMERIC',
        ]];
    }

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
            echo '<p>' . get_the_excerpt() . '</p>';
        }
    } else {
        echo '<p>Посты не найдены.</p>';
    }
    wp_reset_postdata();
    wp_die();
}

Не забудьте локализовать скрипт и передать ajaxurl и nonce:

function twop_ru_enqueue_scripts() {
    wp_enqueue_script('twop-ajax-filter', get_template_directory_uri() . '/js/filter.js', ['jquery'], null, true);
    wp_localize_script('twop-ajax-filter', 'filter_vars', [
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('2wp_filter_nonce'),
    ]);
}
add_action('wp_enqueue_scripts', 'twop_ru_enqueue_scripts');

Расширение фильтрации: добавление кастомных типов записей и сложных условий

Фильтр можно легко расширить для поддержки кастомных типов записей, например, если у вас есть тип product или portfolio. Для этого добавьте параметр post_type из формы и учитывайте его в запросе.

Также возможна сложная логика с relation в meta_query или tax_query, например:

$args['meta_query'] = [
    'relation' => 'AND',
    [
        'key' => 'price',
        'value' => 1000,
        'compare' => '<',
        'type' => 'NUMERIC',
    ],
    [
        'key' => 'in_stock',
        'value' => '1',
        'compare' => '=',
    ],
];

Это позволит отфильтровать товары, у которых цена меньше 1000 и которые есть в наличии.

Как использовать плагины для создания фильтров без кода

Если вы хотите быстрее получить фильтры без написания кода, обратите внимание на плагины из каталога на wpshop.ru. Например:

  • Clearfy Pro — оптимизация и расширение функционала, включая улучшенную фильтрацию.
  • ABC Pagination — гибкая постраничная навигация, которая отлично работает с кастомными запросами.
  • Expert Review — если важны рейтинги и отзывы, можно интегрировать их в фильтрацию.

С этими плагинами вы сможете создать удобный интерфейс фильтрации с минимальными усилиями, при этом сохранив гибкость и производительность.

Советы по оптимизации производительности фильтров

При работе с фильтрами на больших сайтах важно учитывать оптимизацию запросов, чтобы не нагружать базу данных.

  • Используйте индексы для метаполей, по которым фильтруете.
  • Кэшируйте результаты фильтрации с помощью Transients API или плагинов кеширования.
  • Ограничивайте количество выводимых постов и используйте пагинацию.
  • Избегайте избыточного количества условий в meta_query и tax_query, старайтесь объединять параметры.

Например, можно кэшировать результат AJAX-запроса так:

function twop_ru_get_filtered_posts_cached($args) {
    $cache_key = 'twop_filtered_' . md5(serialize($args));
    $posts_html = get_transient($cache_key);
    if (!$posts_html) {
        $query = new WP_Query($args);
        ob_start();
        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
                echo '<p>' . get_the_excerpt() . '</p>';
            }
        } else {
            echo '<p>Посты не найдены.</p>';
        }
        wp_reset_postdata();
        $posts_html = ob_get_clean();
        set_transient($cache_key, $posts_html, HOUR_IN_SECONDS);
    }
    return $posts_html;
}

Это снизит нагрузку на сервер при повторных запросах с одинаковыми параметрами.

Как использовать Customizer для создания настроек темы WordPress
18.02.2026
Автоматическое создание миниатюр (thumbnail) для картинок в WordPress
01.12.2025
Массовое изменение и удаление атрибутов alt у изображений в WordPress
14.02.2026
Создать и использовать собственный тип записи (Custom Post Type) в WordPress с примерами кода
14.01.2026
Как запретить доступ к определённому контенту по ролям в WordPress
19.01.2026