Как создать динамический список постов с фильтром на AJAX в WordPress

Динамические списки постов с фильтрами — частая задача при разработке сайтов на WordPress. Они позволяют пользователям быстро находить нужный контент без перезагрузки страницы. В этой статье подробно разберём, как создать такой список с использованием AJAX и PHP, рассмотрим примеры кода и оптимизации.

Зачем использовать AJAX для фильтрации постов в WordPress

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

Кроме этого, AJAX-фильтры снижают нагрузку на сервер и уменьшают трафик, так как отправляются только необходимые данные, а не весь HTML страницы.

Для реализации потребуется написать PHP-функцию, которая будет обрабатывать AJAX-запросы, и JavaScript-код, который будет отправлять запросы и обновлять список постов на странице.

Создание PHP-функции для обработки AJAX-запроса

Начнём с добавления функции в файл functions.php вашей темы или в свой плагин. Эта функция будет получать параметры фильтра из запроса, формировать WP_Query и возвращать HTML с отфильтрованными постами.

function wppuzzle_get_filtered_posts() {
    // Проверяем nonce для безопасности
    check_ajax_referer('wppuzzle_filter_nonce', 'nonce');

    $category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
    $posts_per_page = 5;

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

    if ($category) {
        $args['category_name'] = $category;
    }

    $query = new WP_Query($args);

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

    wp_die();
}
add_action('wp_ajax_wppuzzle_filter_posts', 'wppuzzle_get_filtered_posts');
add_action('wp_ajax_nopriv_wppuzzle_filter_posts', 'wppuzzle_get_filtered_posts');

Здесь мы создаём WP_Query с параметром категории, если он передан, и выводим заголовок и краткое описание поста.

JavaScript для отправки AJAX-запроса и обновления контента

Теперь добавим JS-код, который будет реагировать на изменение фильтра и отправлять AJAX-запрос.

jQuery(document).ready(function($){
    $('#wppuzzle-category-filter').on('change', function(){
        var category = $(this).val();
        $.ajax({
            url: wppuzzle_ajax_object.ajax_url,
            type: 'POST',
            data: {
                action: 'wppuzzle_filter_posts',
                category: category,
                nonce: wppuzzle_ajax_object.nonce
            },
            beforeSend: function() {
                $('#wppuzzle-post-list').html('<p>Загрузка...</p>');
            },
            success: function(data) {
                $('#wppuzzle-post-list').html(data);
            },
            error: function() {
                $('#wppuzzle-post-list').html('<p>Произошла ошибка, попробуйте позже.</p>');
            }
        });
    });
});

Этот скрипт слушает изменение select с id wppuzzle-category-filter и отправляет выбранное значение на сервер. Затем обновляет блок с постами.

Подключение скрипта и локализация переменных

Чтобы JS-запрос знал URL для AJAX и nonce, добавим в PHP код для подключения скрипта и передачи данных:

function wppuzzle_enqueue_scripts() {
    wp_enqueue_script('wppuzzle-filter', get_template_directory_uri() . '/js/wppuzzle-filter.js', ['jquery'], null, true);

    wp_localize_script('wppuzzle-filter', 'wppuzzle_ajax_object', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wppuzzle_filter_nonce')
    ]);
}
add_action('wp_enqueue_scripts', 'wppuzzle_enqueue_scripts');

Не забудьте создать файл wppuzzle-filter.js в папке js вашей темы и вставить туда JS-код.

HTML-разметка фильтра и контейнера для постов

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

<select id="wppuzzle-category-filter">
    <option value="">Все категории</option>
    <option value="novosti">Новости</option>
    <option value="stati">Статьи</option>
</select>

<div id="wppuzzle-post-list">
    <!-- Здесь будет список постов -->
</div>

Можно динамически вывести категории через wp_list_categories() или вручную, если категорий немного.

Советы по оптимизации и расширению функционала

1. Добавьте пагинацию с подгрузкой следующей страницы через AJAX, чтобы не загружать сразу много постов.

2. Используйте транзиенты или объектный кеш для кеширования результата WP_Query, чтобы снизить нагрузку на базу.

3. Расширьте фильтр дополнительными параметрами — тегами, датами публикации, пользовательскими полями.

4. Внедрите обработку ошибок и уведомления об отсутствии результатов для лучшего UX.

5. Для визуальной части применяйте анимации загрузки и плавное появление новых постов.

Пример расширения фильтра по дате публикации

Добавим фильтр по году публикации. Для этого расширим JS и PHP код.

В HTML добавьте ещё один селект:

<select id="wppuzzle-year-filter">
    <option value="">Все годы</option>
    <option value="2024">2024</option>
    <option value="2023">2023</option>
</select>

В JS измените обработчик, чтобы учитывать оба фильтра:

$('#wppuzzle-category-filter, #wppuzzle-year-filter').on('change', function(){
    var category = $('#wppuzzle-category-filter').val();
    var year = $('#wppuzzle-year-filter').val();
    $.ajax({
        url: wppuzzle_ajax_object.ajax_url,
        type: 'POST',
        data: {
            action: 'wppuzzle_filter_posts',
            category: category,
            year: year,
            nonce: wppuzzle_ajax_object.nonce
        },
        beforeSend: function() {
            $('#wppuzzle-post-list').html('<p>Загрузка...</p>');
        },
        success: function(data) {
            $('#wppuzzle-post-list').html(data);
        },
        error: function() {
            $('#wppuzzle-post-list').html('<p>Произошла ошибка, попробуйте позже.</p>');
        }
    });
});

В PHP добавьте обработку года:

function wppuzzle_get_filtered_posts() {
    check_ajax_referer('wppuzzle_filter_nonce', 'nonce');

    $category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
    $year = isset($_POST['year']) ? intval($_POST['year']) : 0;

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

    if ($category) {
        $args['category_name'] = $category;
    }
    if ($year) {
        $args['year'] = $year;
    }

    $query = new WP_Query($args);

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

    wp_die();
}

Заключение

Создание динамического списка постов с фильтрацией на AJAX в WordPress — отличный способ улучшить удобство сайта и сделать интерфейс более отзывчивым. В статье рассмотрен базовый пример с фильтрацией по категории и году, который можно расширять под любые задачи.

Для быстрого старта можно использовать плагины, например, ABC Pagination для удобной пагинации, или Clearfy Pro для оптимизации работы сайта.

Как удалить заблокированные и повреждённые товары в WooCommerce
11.05.2026
Как создать плагин для WordPress с настройками
19.11.2025
Как создать и обновлять кастомные таблицы в WordPress с помощью wpdb
26.02.2026
Автоматическое удаление старых transient данных в WordPress
16.02.2026
Как удалить повторяющиеся атрибуты товара в WooCommerce
05.06.2026