Фильтрация постов по мета-данным — частая задача при разработке сложных сайтов на WordPress. Например, если вы хотите вывести список товаров, мероприятий или статей, отфильтровав их по дополнительным параметрам, которые не входят в стандартные поля WordPress, то нужно работать с пользовательскими мета-данными (custom fields). В этой статье мы подробно разберём, как создать уникальный, гибкий и эффективный фильтр постов по мета-данным с помощью WP_Query и собственных функций.
Что такое мета-данные в WordPress и зачем фильтровать по ним
Мета-данные — это дополнительные данные, которые можно сохранить к любому посту, странице, пользователю или другому объекту WordPress. Они хранятся в таблице wp_postmeta и имеют ключ и значение. Примеры мета-данных: цена товара, дата события, рейтинг, цвет и т.д.
Фильтрация по мета-данным позволяет выводить только те записи, которые соответствуют определённым критериям. Это особенно полезно для каталогов, интернет-магазинов, портфолио и других проектов, где стандартных таксономий недостаточно.
Чтобы эффективно использовать фильтры по мета-данным, нужно знать, как формировать запросы, создавать интерфейс фильтрации и оптимизировать работу сайта.
Создание базового фильтра по мета-данным с WP_Query
Самый простой способ — использовать параметр meta_query в WP_Query. Рассмотрим пример, где нужно вывести посты с мета-данным price меньше 1000:
function wphow_get_posts_by_price() {
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'price',
'value' => 1000,
'compare' => '<',
'type' => 'NUMERIC'
]
]
];
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
echo '<h3>' . get_the_title() . '</h3>';
echo '<p>Цена: ' . get_post_meta(get_the_ID(), 'price', true) . '</p>';
}
} else {
echo '<p>Посты не найдены.</p>';
}
wp_reset_postdata();
}
Этот код можно вызвать в шаблоне, чтобы вывести отфильтрованные посты. Но это только базовый пример без интерфейса для выбора фильтров пользователем.
Создание динамического пользовательского фильтра с формой и WP_Query
Чтобы пользователи могли фильтровать посты, создадим HTML-форму, которая отправляет параметры фильтрации через GET-запрос. Затем обработаем эти параметры в WP_Query.
Пример формы фильтра
<form method="GET" action="">
<label>Максимальная цена:</label>
<input type="number" name="max_price" value="<?php echo isset($_GET['max_price']) ? intval($_GET['max_price']) : ''; ?>" />
<label>Цвет:</label>
<select name="color">
<option value="">Любой</option>
<option value="red" <?php selected($_GET['color'] ?? '', 'red'); ?>>Красный</option>
<option value="blue" <?php selected($_GET['color'] ?? '', 'blue'); ?>>Синий</option>
<option value="green" <?php selected($_GET['color'] ?? '', 'green'); ?>>Зелёный</option>
</select>
<button type="submit">Фильтровать</button>
</form>
Обработка и формирование meta_query
function wphow_filter_posts_by_meta() {
$meta_query = ['relation' => 'AND'];
if (!empty($_GET['max_price'])) {
$max_price = intval($_GET['max_price']);
$meta_query[] = [
'key' => 'price',
'value' => $max_price,
'compare' => '<=',
'type' => 'NUMERIC'
];
}
if (!empty($_GET['color'])) {
$color = sanitize_text_field($_GET['color']);
$meta_query[] = [
'key' => 'color',
'value' => $color,
'compare' => '='
];
}
$args = [
'post_type' => 'product',
'meta_query' => $meta_query
];
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li>' . get_the_title() . ' - Цена: ' . get_post_meta(get_the_ID(), 'price', true) . ', Цвет: ' . get_post_meta(get_the_ID(), 'color', true) . '</li>';
}
echo '</ul>';
} else {
echo '<p>Нет подходящих товаров.</p>';
}
wp_reset_postdata();
}
Вызовите эту функцию в нужном месте шаблона после формы, чтобы вывести отфильтрованные записи.
Оптимизация фильтров по мета-данным: индексы и кэширование
Фильтрация по мета-данным может сильно нагружать базу данных, особенно при большом количестве записей. Чтобы ускорить работу:
- Добавьте индексы на колонки
meta_keyиmeta_valueв таблицеwp_postmeta(если вы уверены в своих действиях и сделали резервную копию). - Используйте транзиенты (
set_transient) для кэширования результатов запросов, если данные меняются нечасто. - Ограничивайте количество результатов и используйте пагинацию.
Если вы хотите использовать готовое решение, обратите внимание на плагин Clearfy Pro, который среди множества инструментов содержит расширенные возможности оптимизации запросов и управления мета-данными.
Создание сложных фильтров с несколькими условиями и операторами
WP_Query поддерживает сложные запросы с операторами AND и OR внутри meta_query. Например, можно вывести посты, где цена от 500 до 1500, и цвет — красный или синий:
$args = [
'post_type' => 'product',
'meta_query' => [
'relation' => 'AND',
[
'key' => 'price',
'value' => [500, 1500],
'compare' => 'BETWEEN',
'type' => 'NUMERIC'
],
[
'relation' => 'OR',
[
'key' => 'color',
'value' => 'red',
'compare' => '='
],
[
'key' => 'color',
'value' => 'blue',
'compare' => '='
]
]
]
];
$query = new WP_Query($args);
Такие запросы позволяют создавать гибкие фильтры для пользователей.
Интеграция с AJAX для динамической фильтрации без перезагрузки страницы
Чтобы улучшить UX, фильтр можно сделать AJAX-ориентированным. При изменении параметров формы запрос будет отправляться на сервер без перезагрузки страницы, а результаты обновляться динамически.
Примерный план действий:
- Добавить JavaScript-код, который при изменении формы отправляет AJAX-запрос.
- Создать обработчик AJAX в functions.php, который формирует WP_Query с параметрами из запроса.
- Вернуть HTML с результатами и обновить блок с постами на странице.
Для упрощения AJAX-запросов можно использовать jQuery и стандартные WordPress AJAX хуки wp_ajax_ и wp_ajax_nopriv_.
Пример JS для отправки формы AJAX
jQuery(document).ready(function($){
$('#filter-form').on('change', 'input, select', function(){
var data = $('#filter-form').serialize();
$.ajax({
url: wphow_ajax_object.ajax_url,
type: 'GET',
data: data + '&action=wphow_filter_posts',
success: function(response){
$('#filter-results').html(response);
}
});
});
});
Пример PHP-обработчика AJAX
add_action('wp_ajax_wphow_filter_posts', 'wphow_ajax_filter_posts');
add_action('wp_ajax_nopriv_wphow_filter_posts', 'wphow_ajax_filter_posts');
function wphow_ajax_filter_posts() {
// Аналогично формируем meta_query из $_GET
// ... код из предыдущего примера
// Выводим результаты
wphow_filter_posts_by_meta();
wp_die();
}
Заключение
Фильтрация постов по мета-данным — мощный инструмент для кастомизации вывода контента на WordPress. С помощью meta_query WP_Query можно создавать как простые, так и сложные условия фильтрации. Добавление пользовательского интерфейса с формами и AJAX позволяет сделать сайт удобным и современным.
Для расширения возможностей и оптимизации рекомендуется рассмотреть плагины, например, Clearfy Pro, которые помогут избежать типичных ошибок и ускорить работу.
Используйте приведённые примеры кода как основу для своих проектов и адаптируйте под конкретные задачи.