В этой статье подробно разберём, как реализовать в WordPress динамический список постов с возможностью фильтрации по категориям и тегам, а также с поддержкой пагинации. Это частая задача для сайтов с большим количеством контента, когда нужно удобное и быстрое представление материалов для пользователей.
Почему стоит создавать кастомный список постов с фильтром и пагинацией
Стандартные архивы WordPress дают базовые возможности, но часто недостаточно гибки для специфических задач. Например, вам может понадобиться:
- Фильтрация по нескольким таксономиям одновременно.
- Работа с нестандартными полями и мета-данными.
- Плавная подгрузка контента без перезагрузки страницы.
- Удобная навигация с пагинацией или бесконечной прокруткой.
Использование WP_Query для создания кастомного списка постов
Основой решения будет класс WP_Query, позволяющий гибко получать записи по параметрам.
Допустим, нам нужно вывести посты с возможностью фильтрации по категориям и тегам, а также с постраничной навигацией.
Пример базового запроса с фильтрацией
function wpconsult_get_filtered_posts() {
$paged = isset($_GET['paged']) ? intval($_GET['paged']) : 1;
$category = isset($_GET['category']) ? sanitize_text_field($_GET['category']) : '';
$tag = isset($_GET['tag']) ? sanitize_text_field($_GET['tag']) : '';
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'paged' => $paged,
];
if ($category) {
$args['category_name'] = $category;
}
if ($tag) {
$args['tag'] = $tag;
}
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
// Пагинация
$big = 999999999; // уникальное число для замены
echo paginate_links([
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
'format' => '?paged=%#%',
'current' => max(1, $paged),
'total' => $query->max_num_pages,
]);
} else {
echo '<p>Посты не найдены.</p>';
}
wp_reset_postdata();
}Этот код можно вызвать в нужном шаблоне темы, например, в отдельной странице или архиве.
Создание пользовательского интерфейса фильтрации
Чтобы пользователи могли выбирать категории и теги, добавим форму фильтрации.
Пример формы:
<form method="get" action="">
<select name="category">
<option value="">Все категории</option>
<?php
$categories = get_categories();
foreach ($categories as $cat) {
$selected = (isset($_GET['category']) && $_GET['category'] === $cat->slug) ? 'selected' : '';
echo "<option value='{$cat->slug}' $selected>{$cat->name}</option>";
}
?>
</select>
<select name="tag">
<option value="">Все теги</option>
<?php
$tags = get_tags();
foreach ($tags as $tag) {
$selected = (isset($_GET['tag']) && $_GET['tag'] === $tag->slug) ? 'selected' : '';
echo "<option value='{$tag->slug}' $selected>{$tag->name}</option>";
}
?>
</select>
<button type="submit">Фильтровать</button>
</form>Форма отправляет GET-запрос, который обрабатывается в функции с WP_Query.
Добавление AJAX-загрузки для улучшения UX
Чтобы не перезагружать страницу при смене фильтров или пагинации, можно использовать AJAX. Это улучшит взаимодействие пользователя с сайтом.
Пример минимальной реализации с использованием jQuery:
jQuery(document).ready(function($) {
$('#filter-form select, #filter-form button').on('change click', function(e) {
e.preventDefault();
var data = $('#filter-form').serialize();
$.ajax({
url: wpconsult_ajax_object.ajax_url,
type: 'GET',
data: data + '&action=wpconsult_filter_posts',
success: function(response) {
$('#posts-container').html(response);
},
error: function() {
alert('Ошибка загрузки данных');
}
});
});
});Для этого на стороне PHP нужно зарегистрировать AJAX обработчик:
add_action('wp_ajax_wpconsult_filter_posts', 'wpconsult_handle_filter_posts');
add_action('wp_ajax_nopriv_wpconsult_filter_posts', 'wpconsult_handle_filter_posts');
function wpconsult_handle_filter_posts() {
wpconsult_get_filtered_posts();
wp_die();
}И не забудьте локализовать скрипт в functions.php:
function wpconsult_enqueue_scripts() {
wp_enqueue_script('wpconsult-filter', get_template_directory_uri() . '/js/filter.js', ['jquery'], null, true);
wp_localize_script('wpconsult-filter', 'wpconsult_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php'),
]);
}
add_action('wp_enqueue_scripts', 'wpconsult_enqueue_scripts');Оптимизация и кеширование результатов
При большом объёме данных запросы могут нагружать сервер. Рекомендуется использовать кеширование:
- Использовать Transients API для хранения результатов запросов.
- Кешировать HTML-вывод.
- Использовать специализированные плагины, например, Clearfy Pro для оптимизации.
Пример кеширования с Transient:
function wpconsult_get_filtered_posts_cached() {
$cache_key = 'wpconsult_posts_' . md5(serialize($_GET));
$output = get_transient($cache_key);
if ($output === false) {
ob_start();
wpconsult_get_filtered_posts();
$output = ob_get_clean();
set_transient($cache_key, $output, HOUR_IN_SECONDS);
}
echo $output;
}Вывод
Создание кастомного динамического списка постов с фильтрами и пагинацией — задача, которую можно решить без сторонних плагинов, используя WP_Query, AJAX и кеширование. Такой подход делает сайт более удобным и быстрым для пользователей, а также облегчает поддержку кода.
Для расширения функционала можно интегрировать решения из экосистемы WPSHOP, которые помогут ускорить разработку и улучшить производительность.