В современных проектах на WordPress часто возникает задача реализовать фильтрацию записей по определённым пользовательским метаданным — например, по цене, рейтингу, дате или другим параметрам, которые не входят в стандартные поля. Такой фильтр позволяет пользователю быстро находить нужный контент, улучшая UX и повышая конверсию.
Что такое метаданные в WordPress и зачем нужен динамический фильтр
Метаданные — это дополнительные данные, связанные с записями (постами), которые хранятся в таблице wp_postmeta. Они позволяют расширять функциональность сайта без изменения основной структуры. Пример — свойство "цена" для товаров в интернет-магазине или "уровень сложности" для уроков.
Динамический фильтр — это интерфейс, который подстраивается под доступные метаданные и значения в базе и позволяет пользователю выбирать параметры для отображения только релевантных записей.
В этой статье мы подробно рассмотрим, как реализовать такой фильтр с минимальными затратами ресурсов и с примерами кода.
Подготовка: создание и заполнение метаданных
Для примера создадим тип записей product и добавим метаполе price. Если у вас уже есть метаданные, этот раздел можно пропустить.
function wpboot_register_post_type_product() {
register_post_type('product', [
'labels' => [
'name' => 'Товары',
'singular_name' => 'Товар',
],
'public' => true,
'has_archive' => true,
'supports' => ['title', 'editor', 'custom-fields'],
]);
}
add_action('init', 'wpboot_register_post_type_product');Для заполнения метаданных можно использовать стандартный пользовательский интерфейс или добавить свой метабокс.
Создание формы фильтрации с динамическими значениями
Для динамического создания параметров фильтра нам нужно получить уникальные значения метаполя price из базы.
function wpboot_get_unique_meta_values($meta_key, $post_type = 'product') {
global $wpdb;
$query = $wpdb->prepare(
"SELECT DISTINCT meta_value FROM {$wpdb->postmeta} pm
INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID
WHERE pm.meta_key = %s AND p.post_type = %s AND p.post_status = 'publish'",
$meta_key, $post_type
);
return $wpdb->get_col($query);
}Далее строим форму фильтра с выпадающим списком цен:
$prices = wpboot_get_unique_meta_values('price');
echo '<form method="GET" action="">';
echo '<select name="price_filter">';
echo '<option value="">Все цены</option>';
foreach ($prices as $price) {
$selected = (isset($_GET['price_filter']) && $_GET['price_filter'] == $price) ? 'selected' : '';
echo "<option value=\"$price\" $selected>$price</option>";
}
echo '</select>';
echo '<input type="submit" value="Фильтровать">';
echo '</form>';Обработка фильтра и вывод отфильтрованных записей
Чтобы вывести записи, удовлетворяющие выбранному фильтру, используем WP_Query с параметром meta_query:
function wpboot_filter_products_by_price() {
$meta_query = [];
if (!empty($_GET['price_filter'])) {
$meta_query[] = [
'key' => 'price',
'value' => sanitize_text_field($_GET['price_filter']),
'compare' => '=',
];
}
$args = [
'post_type' => 'product',
'post_status' => 'publish',
'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) . '</li>';
}
echo '</ul>';
} else {
echo '<p>Товары не найдены</p>';
}
wp_reset_postdata();
}Вызовите функцию wpboot_filter_products_by_price() в нужном месте шаблона для вывода отфильтрованных товаров.
Оптимизация и расширение фильтра
Если метаданных много, а выборок много, запросы могут тормозить. Рекомендуется добавить индекс по meta_key и meta_value в базе данных, если это возможно.
Для сложных фильтров с несколькими параметрами используйте массив meta_query с логикой 'relation' => 'AND' или 'OR'. Пример:
$meta_query = [
'relation' => 'AND',
[
'key' => 'price',
'value' => 1000,
'compare' => '<=',
'type' => 'NUMERIC'
],
[
'key' => 'rating',
'value' => 4,
'compare' => '>=',
'type' => 'NUMERIC'
]
];Используйте кастомные типы данных (type) для корректного сравнения чисел и дат.
Рекомендации по плагинам для фильтрации
Если хотите использовать готовые решения, можно обратить внимание на плагины:
- ABC Pagination — расширенный пейджинг и фильтры.
- Clearfy Pro — оптимизация и настройка.
Однако собственный фильтр даст полный контроль и будет легче адаптироваться под ваши задачи.
Вывод
Динамический фильтр по метаданным — мощный инструмент улучшения навигации по сайту на WordPress. Правильная реализация с использованием meta_query и динамическим формированием интерфейса позволяет создавать удобные и быстрые фильтры, которые могут масштабироваться под любые задачи.