Фильтрация контента по пользовательским полям — один из самых частых сценариев в разработке плагинов и кастомных тем WordPress. С её помощью можно позволить пользователю сортировать и отбирать записи по нужным параметрам: цене, типу, агенту, городу и т.д. В этой статье разберём, как сделать фильтрацию записей WordPress через WP_Query и meta_query, создавая плагин с нуля.
Зачем нужна фильтрация по метабоксам
В типичном проекте на WordPress часто используются кастомные типы записей и метабоксы — дополнительные поля, где хранятся данные вроде «цены», «агента», «площади», «статуса» и т.д.
Без фильтрации пользователю приходится просматривать все записи подряд. Фильтр решает это, позволяя динамически выбирать нужные параметры прямо на странице архива, без сложных интерфейсов.
Структура плагина
Для чистоты и масштабируемости лучше заранее организовать шаблоны в плагине:
/my-plugin/
├─ includes/
├─ templates/
│ ├─ parts/
│ │ ├─ content.php
│ │ └─ filter.php
│ └─ archive-property.php
├─ my-plugin.php
content.php— шаблон вывода отдельного элемента (например, недвижимости).filter.php— форма фильтрации.archive-property.php— шаблон архива, где собирается всё вместе.
Шаг 1. Разделяем шаблон контента
Чтобы не перегружать файл архива, контент отдельной карточки лучше вынести в отдельный шаблон.
Используем вспомогательный метод get_template_part() (или собственный, если вы работаете внутри плагина):
$this->get_template_part('parts/content');
Это позволит легко переиспользовать разметку и поддерживать код в порядке.
Шаг 2. Создаём форму фильтрации
В файле filter.php добавим базовую HTML-форму с методом POST и действием, указывающим на текущую страницу:
<form method="POST" action="<?php echo esc_url(get_post_type_archive_link('property')); ?>">
<select name="property_type">
<option value="">Выберите тип</option>
<option value="for_sale">Продажа</option>
<option value="for_rent">Аренда</option>
<option value="sold">Продано</option>
</select>
<input type="text" name="property_price" placeholder="Максимальная цена">
<select name="property_agent">
<option value="">Выберите агента</option>
<?php
$agents = get_posts(['post_type' => 'agent', 'numberposts' => -1]);
foreach ($agents as $agent) {
echo '<option value="' . esc_attr($agent->ID) . '">' . esc_html($agent->post_title) . '</option>';
}
?>
</select>
<input type="submit" name="submit" value="Фильтровать">
</form>
Эта форма будет отправлять выбранные значения на текущую страницу архива, откуда мы их сможем обработать через PHP.
Шаг 3. Обработка формы и создание WP_Query
В archive-property.php проверяем, была ли нажата кнопка фильтрации.
Если да — формируем свой запрос WP_Query, используя meta_query.
$args = [
'post_type' => 'property',
'posts_per_page' => -1,
];
if (!empty($_POST['submit'])) {
$meta_query = ['relation' => 'AND'];
if (!empty($_POST['property_type'])) {
$meta_query[] = [
'key' => 'property_type',
'value' => sanitize_text_field($_POST['property_type']),
'compare' => '=',
];
}
if (!empty($_POST['property_price'])) {
$meta_query[] = [
'key' => 'property_price',
'value' => intval($_POST['property_price']),
'compare' => '<=',
'type' => 'NUMERIC',
];
}
if (!empty($_POST['property_agent'])) {
$meta_query[] = [
'key' => 'property_agent',
'value' => intval($_POST['property_agent']),
'compare' => '=',
];
}
$args['meta_query'] = $meta_query;
}
$query = new WP_Query($args);
Таким образом, если пользователь заполнил форму, мы фильтруем записи по всем выбранным критериям.
Шаг 4. Вывод отфильтрованных результатов
Теперь достаточно заменить стандартный цикл WordPress на:
if ($query->have_posts()) :
while ($query->have_posts()) :
$query->the_post();
$this->get_template_part('parts/content');
endwhile;
else :
echo '<p>Ничего не найдено по заданным параметрам.</p>';
endif;
wp_reset_postdata();
Шаг 5. Сохранение выбранных значений после фильтрации
Чтобы при перезагрузке страницы выбранные значения сохранялись, можно добавить небольшие проверки:
<option value="for_rent" <?php selected($_POST['property_type'] ?? '', 'for_rent'); ?>>Аренда</option>
Аналогично для остальных полей. Это улучшит UX и позволит пользователю видеть активные фильтры.
Шаг 6. Добавляем стили и улучшения
Чтобы фильтр выглядел органично, оберните поля в контейнер:
<div class="property-filter">
<!-- форма -->
</div>
А затем подключите стили для красивого отображения:
.property-filter {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.property-filter select,
.property-filter input {
padding: 6px 10px;
}
Заключение
После реализации всех шагов вы получите гибкую систему фильтрации для кастомного типа записей WordPress.
Фильтр будет работать через WP_Query с meta_query, корректно сохранять выбранные значения и выводить только нужные записи.
Такой подход можно легко расширять:
- добавить фильтр по таксономиям (через
tax_query), - подключить AJAX для динамической подгрузки,
- реализовать предзаполненные фильтры или сохранение поисков.