В этой статье мы рассмотрим, как создать динамический список постов с возможностью фильтрации по категориям и меткам в WordPress. Такая функциональность полезна для сайтов с большим объемом контента, где пользователям важно быстро находить нужные записи. Мы опишем решение без использования тяжелых плагинов, используя собственные WP_Query и AJAX, а также рассмотрим плагины, которые могут упростить задачу.
Зачем нужен динамический список постов с фильтрами
Стандартный архив записей в WordPress отображает все посты, либо посты выбранной категории или метки. Однако, если пользователь хочет одновременно фильтровать по нескольким параметрам — например, категория + метка + дата — стандартные возможности ограничены. Динамический список с фильтрами позволяет:
- Улучшить пользовательский опыт, предоставляя удобные инструменты поиска.
- Ускорить навигацию по сайту.
- Снизить нагрузку на сервер за счет AJAX-подгрузки.
- Создать уникальный дизайн и логику отображения.
Основы создания фильтруемого списка постов с помощью WP_Query
Для начала создадим базовый WP_Query, который получает посты с заданными параметрами. В качестве фильтров будем использовать категории и метки — это самые распространённые таксономии.
Пример функции для получения постов с фильтрами:
function wpone_get_filtered_posts($category_slug = '', $tag_slug = '') {
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
];
if ($category_slug) {
$args['category_name'] = $category_slug;
}
if ($tag_slug) {
$args['tag'] = $tag_slug;
}
$query = new WP_Query($args);
return $query;
}Далее можно вывести список постов из объекта WP_Query:
function wpone_display_filtered_posts($category_slug = '', $tag_slug = '') {
$query = wpone_get_filtered_posts($category_slug, $tag_slug);
if ($query->have_posts()) {
echo '<ul class="wpone-post-list">';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
wp_reset_postdata();
} else {
echo '<p>Посты не найдены.</p>';
}
}Добавляем AJAX-фильтрацию постов по категориям и меткам
Чтобы не перегружать страницу при каждом выборе фильтра, реализуем динамическую подгрузку через AJAX. Для этого:
- Создаем HTML-форму с выпадающими списками категорий и меток.
- Подключаем JavaScript для отправки AJAX-запроса при выборе фильтра.
- Обрабатываем AJAX-запрос на стороне WordPress и возвращаем обновленный список.
HTML и JavaScript
Пример простого HTML с двумя селектами:
<form id="wpone-filter-form">
<select name="category" id="wpone-category">
<option value="">Все категории</option>
<?php
$categories = get_categories();
foreach ($categories as $cat) {
echo '<option value="' . esc_attr($cat->slug) . '">' . esc_html($cat->name) . '</option>';
}
?>
</select>
<select name="tag" id="wpone-tag">
<option value="">Все метки</option>
<?php
$tags = get_tags();
foreach ($tags as $tag) {
echo '<option value="' . esc_attr($tag->slug) . '">' . esc_html($tag->name) . '</option>';
}
?>
</select>
</form>
<div id="wpone-posts-container"><!-- Здесь будет вывод --></div>
<script>
document.getElementById('wpone-filter-form').addEventListener('change', function() {
var category = document.getElementById('wpone-category').value;
var tag = document.getElementById('wpone-tag').value;
var data = new FormData();
data.append('action', 'wpone_filter_posts');
data.append('category', category);
data.append('tag', tag);
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
method: 'POST',
credentials: 'same-origin',
body: data
})
.then(response => response.text())
.then(html => {
document.getElementById('wpone-posts-container').innerHTML = html;
});
});
</script>Обработка AJAX-запроса в functions.php
Добавим обработчик, который вызовет функцию получения и вывода постов:
add_action('wp_ajax_wpone_filter_posts', 'wpone_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpone_filter_posts', 'wpone_ajax_filter_posts');
function wpone_ajax_filter_posts() {
$category = sanitize_text_field($_POST['category'] ?? '');
$tag = sanitize_text_field($_POST['tag'] ?? '');
wpone_display_filtered_posts($category, $tag);
wp_die();
}Рекомендации по плагинам для фильтрации
Если вы предпочитаете использовать готовые решения, обратите внимание на следующие плагины:
- FacetWP — мощный плагин для фильтрации по таксономиям, метаполям и другим параметрам. Плагин платный, но очень гибкий.
- Search & Filter — бесплатный и простой в настройке плагин для создания фильтров по категориям, меткам, полям и типам записей.
- WPONE AJAX (из вашей коллекции) — подойдет для реализации AJAX-действий, можно использовать в связке с кастомным кодом.
Использование плагинов удобно для быстрого результата, но при необходимости гибкой и легкой реализации лучше написать собственное решение, как показано выше.
Советы по оптимизации и UX фильтрации
Чтобы фильтрация работала быстро и удобно, рекомендуем:
- Кэшировать результаты WP_Query с помощью Transients или Object Cache.
- Использовать пагинацию, чтобы не грузить все посты сразу.
- Добавлять индексы по метаполям в базе для ускорения запросов.
- Показывать пользователю индикаторы загрузки при AJAX-запросах.
- Убедиться, что на мобильных устройствах фильтры удобно использовать.
Пример расширения: фильтрация по дате и произвольному полю
Для расширения фильтров можно добавить дату публикации и метаполя, например, цену или рейтинг. В WP_Query это делается через параметры meta_query и date_query.
function wpone_get_filtered_posts_extended($category_slug = '', $tag_slug = '', $date_after = '', $meta_key = '', $meta_value = '') {
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
];
if ($category_slug) {
$args['category_name'] = $category_slug;
}
if ($tag_slug) {
$args['tag'] = $tag_slug;
}
if ($date_after) {
$args['date_query'] = [
[
'after' => $date_after,
'inclusive' => true,
]
];
}
if ($meta_key && $meta_value) {
$args['meta_query'] = [
[
'key' => $meta_key,
'value' => $meta_value,
'compare' => '=',
]
];
}
$query = new WP_Query($args);
return $query;
}Это позволяет создать мощный и гибкий фильтр, который подстроится под любые задачи.