Динамические каталоги — отличный способ эффективно организовать и представить большой объем контента на сайте WordPress. Особенно полезны каталоги с поддержкой AJAX и фильтров, которые позволяют пользователям быстро находить нужные записи без перезагрузки страницы. В этой статье подробно рассмотрим, как создать такой каталог с нуля, используя стандартные средства WordPress и минимальное количество сторонних плагинов.
Зачем нужны динамические каталоги с AJAX и фильтрами в WordPress
При большом количестве записей на сайте статическая пагинация и фильтрация часто становятся неудобными — каждое обновление страницы замедляет работу и ухудшает пользовательский опыт. AJAX позволяет обновлять список записей асинхронно, без перезагрузки, а фильтры помогают быстро сузить выборку по категориям, тегам, метаполям и другим параметрам.
Создание собственного решения обеспечивает гибкость и позволяет точно настроить функционал под задачи вашего сайта. Кроме того, вы сможете оптимизировать запросы к базе данных и контролировать вывод, что важно для производительности и SEO.
Основные шаги по созданию динамического каталога в WordPress
Построим пример каталога, который выводит записи кастомного типа product с фильтрацией по таксономии product_category и ценовому диапазону. Обновление результатов будет происходить на AJAX.
1. Регистрация кастомного типа записи и таксономии
Для начала добавим кастомный тип и таксономию в файл темы functions.php или в свой плагин:
function premiumwp_register_product_cpt() {
$labels = [
'name' => 'Товары',
'singular_name' => 'Товар',
'menu_name' => 'Каталог товаров',
];
$args = [
'labels' => $labels,
'public' => true,
'has_archive' => true,
'supports' => ['title', 'editor', 'thumbnail', 'custom-fields'],
'rewrite' => ['slug' => 'products'],
];
register_post_type('product', $args);
register_taxonomy('product_category', 'product', [
'label' => 'Категории товаров',
'hierarchical' => true,
'rewrite' => ['slug' => 'product-category'],
]);
}
add_action('init', 'premiumwp_register_product_cpt');
Это позволит создавать в административной панели товары с категориями.
2. Создание шаблона с фильтрами и контейнером для списка товаров
В нужном шаблоне (например, в archive-product.php или на отдельной странице) выводим фильтры и блок для вывода списка товаров:
<div id="premiumwp-filters">
<select id="premiumwp-category-filter">
<option value="">Все категории</option>
<?php
$categories = get_terms(['taxonomy' => 'product_category', 'hide_empty' => true]);
foreach ($categories as $cat) {
echo '<option value="' . esc_attr($cat->slug) . '">' . esc_html($cat->name) . '</option>';
}
?>
</select>
<input type="number" id="premiumwp-price-min" placeholder="Мин. цена" />
<input type="number" id="premiumwp-price-max" placeholder="Макс. цена" />
<button id="premiumwp-filter-button">Применить</button>
</div>
<div id="premiumwp-products-list">
<!-- Здесь будут загружаться товары -->
</div>
Так мы создаём элементы управления для выбора категории и ценового диапазона, а также контейнер для вывода результатов.
3. Написание AJAX-обработчика на стороне сервера
Создадим функцию, которая будет формировать WP_Query с учетом фильтров и возвращать сгенерированный HTML. Также подключим её к AJAX-запросам.
function premiumwp_ajax_filter_products() {
$category = sanitize_text_field($_POST['category'] ?? '');
$price_min = floatval($_POST['price_min'] ?? 0);
$price_max = floatval($_POST['price_max'] ?? 0);
$tax_query = [];
if ($category) {
$tax_query[] = [
'taxonomy' => 'product_category',
'field' => 'slug',
'terms' => $category,
];
}
$meta_query = [];
if ($price_min > 0 || $price_max > 0) {
$meta_query[] = [
'key' => 'price',
'value' => [$price_min, $price_max],
'compare' => 'BETWEEN',
'type' => 'NUMERIC',
];
}
$args = [
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => $tax_query,
'meta_query' => $meta_query,
];
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start();
echo '<ul class="premiumwp-products">';
while ($query->have_posts()) {
$query->the_post();
$price = get_post_meta(get_the_ID(), 'price', true);
echo '<li><h3>' . get_the_title() . '</h3><p>Цена: ' . esc_html($price) . '</p></li>';
}
echo '</ul>';
wp_reset_postdata();
$html = ob_get_clean();
} else {
$html = '<p>Товары не найдены.</p>';
}
wp_send_json_success(['html' => $html]);
}
add_action('wp_ajax_premiumwp_filter_products', 'premiumwp_ajax_filter_products');
add_action('wp_ajax_nopriv_premiumwp_filter_products', 'premiumwp_ajax_filter_products');
Обратите внимание: значение цены хранится в метаполе price. Для вашего сайта может потребоваться адаптация.
4. Подключение JavaScript для отправки AJAX-запроса и обновления каталога
Добавим скрипт, который будет отслеживать нажатие кнопки фильтра и отправлять параметры на сервер:
jQuery(document).ready(function($) {
$('#premiumwp-filter-button').on('click', function() {
var category = $('#premiumwp-category-filter').val();
var priceMin = $('#premiumwp-price-min').val();
var priceMax = $('#premiumwp-price-max').val();
$.ajax({
url: premiumwp_ajax_object.ajax_url,
method: 'POST',
data: {
action: 'premiumwp_filter_products',
category: category,
price_min: priceMin,
price_max: priceMax
},
beforeSend: function() {
$('#premiumwp-products-list').html('<p>Загрузка...</p>');
},
success: function(response) {
if (response.success) {
$('#premiumwp-products-list').html(response.data.html);
} else {
$('#premiumwp-products-list').html('<p>Ошибка загрузки товаров.</p>');
}
},
error: function() {
$('#premiumwp-products-list').html('<p>Ошибка запроса.</p>');
}
});
});
});
Не забудьте локализовать скрипт и передать параметр ajax_url в PHP:
function premiumwp_enqueue_scripts() {
wp_enqueue_script('premiumwp-filter-js', get_template_directory_uri() . '/js/premiumwp-filter.js', ['jquery'], null, true);
wp_localize_script('premiumwp-filter-js', 'premiumwp_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php')
]);
}
add_action('wp_enqueue_scripts', 'premiumwp_enqueue_scripts');
Дополнительные советы по улучшению каталога
Использование пагинации с AJAX
Для удобства можно добавить постраничную навигацию, которая также будет работать через AJAX, подгружая дополнительные товары без перезагрузки. Для этого расширьте AJAX-обработчик, принимая параметр текущей страницы и передавайте его в WP_Query.
Оптимизация запросов и кэширование
Если товаров много, рекомендуем использовать кэширование результатов AJAX-запросов, например, с помощью Transients API. Это существенно снизит нагрузку на сервер и ускорит отклик.
Использование готовых плагинов для фильтров
Если хотите сэкономить время, можно использовать плагины как Clearfy Pro — они содержат расширенные возможности для фильтрации и оптимизации запросов, а также интеграцию с AJAX.
Вывод
Создание динамического каталога с AJAX и фильтрами — задача, требующая понимания работы WP_Query, AJAX и JavaScript. Используя подход, описанный выше, вы получите гибкий и удобный каталог, который улучшит пользовательский опыт и ускорит поиск нужной информации на сайте. При необходимости можно расширять функционал за счёт пагинации, сортировки и дополнительной фильтрации.