Advanced Custom Fields (ACF) — один из самых популярных плагинов для добавления и управления дополнительными полями в WordPress. Часто возникает задача — отобразить на сайте записи, отфильтрованные по значениям этих полей. В этой статье подробно разберём, как правильно строить запросы WP_Query с фильтрацией по полям ACF, учитывая разные типы данных и особенности плагина.
Основы работы с WP_Query и мета-запросами
Для фильтрации записей по дополнительным полям ACF обычно используется параметр meta_query в WP_Query. Это массив условий, который позволяет искать записи по значениям метаданных.
Пример базового запроса, где мы ищем записи, у которых поле с ключом price больше 1000:
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'price',
'value' => 1000,
'compare' => '>',
'type' => 'NUMERIC',
],
],
];
$query = new WP_Query($args);Важно правильно указывать параметр type, так как по умолчанию сравнение происходит как строковое.
Фильтрация по разным типам полей ACF
Текстовые и числовые поля
Для текстовых полей используйте type => 'CHAR' или опустите, поскольку это значение по умолчанию. Для числовых полей — обязательно указывайте type => 'NUMERIC', чтобы сравнения работали корректно.
Пример фильтрации по текстовому полю author_name:
$args = [
'post_type' => 'book',
'meta_query' => [
[
'key' => 'author_name',
'value' => 'Иванов',
'compare' => 'LIKE',
],
],
];
$query = new WP_Query($args);Поля с выбором (select, checkbox, radio)
Для полей выбора значения хранятся как строки. При фильтрации по чекбоксам, которые позволяют множественный выбор, значения хранятся в сериализованном массиве, поэтому простое сравнение не сработает.
Для чекбоксов можно использовать оператор LIKE, но будьте аккуратны с совпадениями:
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'colors',
'value' => 'red',
'compare' => 'LIKE',
],
],
];Если нужны точные совпадения, лучше использовать кастомные таблицы или дополнительные таксономии.
Поля дата и время
Поля типа дата хранятся в формате YYYYMMDD. Для фильтрации по ним используйте type => 'DATE'. Например, чтобы получить записи с датой больше 2023-01-01:
$args = [
'post_type' => 'event',
'meta_query' => [
[
'key' => 'event_date',
'value' => '20230101',
'compare' => '>=',
'type' => 'DATE',
],
],
];Сложные условия: несколько фильтров и группы
WP_Query позволяет строить сложные мета-запросы с логическими операторами AND и OR. Например, найти записи, у которых поле price больше 1000 и цвет red:
$args = [
'post_type' => 'product',
'meta_query' => [
'relation' => 'AND',
[
'key' => 'price',
'value' => 1000,
'compare' => '>',
'type' => 'NUMERIC',
],
[
'key' => 'colors',
'value' => 'red',
'compare' => 'LIKE',
],
],
];Это даёт гибкость при построении фильтров для каталогов или страниц с товарами.
Реальный пример: фильтр товаров с плагином ABC Pagination
Если на вашем сайте используется плагин ABC Pagination для постраничной навигации, его легко интегрировать с WP_Query и мета-запросами.
Пример запроса с фильтром и пагинацией:
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$args = [
'post_type' => 'product',
'posts_per_page' => 10,
'paged' => $paged,
'meta_query' => [
[
'key' => 'price',
'value' => [500, 2000],
'compare' => 'BETWEEN',
'type' => 'NUMERIC',
],
],
];
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
// вывод контента
}
abc_pagination(['query' => $query]);
wp_reset_postdata();
}Оптимизация запросов и кеширование
Фильтрация по мета-полям может замедлять сайт, особенно при большом количестве записей. Рекомендуется:
- Добавлять индексы на поля
meta_keyиmeta_valueв базе данных; - Использовать кеширование запросов — например, через Transients API или плагин Clearfy Pro (подробнее);
- По возможности заменять сложные запросы мета-полей на таксономии — они индексируются эффективнее.
Создание кастомного фильтра с функциями wpco
Для удобства можно создать свою функцию, которая будет формировать WP_Query с фильтрацией по ACF. Например:
function wpco_get_filtered_posts_by_acf($post_type, $filters, $paged = 1) {
$meta_query = [];
foreach ($filters as $filter) {
$meta_query[] = [
'key' => $filter['key'],
'value' => $filter['value'],
'compare' => $filter['compare'] ?? '=',
'type' => $filter['type'] ?? 'CHAR',
];
}
$args = [
'post_type' => $post_type,
'paged' => $paged,
'meta_query' => $meta_query,
];
return new WP_Query($args);
}Использование:
$filters = [
['key' => 'price', 'value' => 1000, 'compare' => '>=', 'type' => 'NUMERIC'],
['key' => 'colors', 'value' => 'blue', 'compare' => 'LIKE'],
];
$query = wpco_get_filtered_posts_by_acf('product', $filters, get_query_var('paged', 1));Это упрощает переиспользование кода и поддерживает чистоту проекта.