Advanced Custom Fields (ACF) — один из самых популярных плагинов для расширения функционала WordPress за счет добавления удобных пользовательских полей. Часто возникает задача не просто вывести записи, а отфильтровать их по значениям этих полей. В этой статье подробно разберем, как правильно строить запросы WP_Query с фильтрацией по полям ACF, рассмотрим разные типы полей и примеры кода для наиболее частых сценариев.
Что такое фильтрация по полям ACF и зачем она нужна
Поля ACF хранятся в таблице wp_postmeta, а не в основной таблице постов. Чтобы фильтровать записи по значениям этих полей, нужно использовать параметры meta_query в WP_Query. Это позволяет, например, вывести только товары с ценой выше 1000 или статьи, где указано определённое значение в кастомном поле.
Без правильной настройки meta_query вы получите либо пустой результат, либо будете вынуждены делать дополнительную обработку на PHP после получения всех записей, что неэффективно.
Рассмотрим, как строить такие запросы на практике с примерами.
Фильтрация по простым текстовым и числовым полям ACF
Для простых полей, например, текстовых, числовых или селектов, фильтрация строится через meta_query с ключом поля и сравнением по значению.
Пример: вывести записи, где поле ACF product_price больше 1000.
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'product_price',
'value' => 1000,
'compare' => '>',
'type' => 'NUMERIC'
]
]
];
$query = new WP_Query($args);
Важно указывать тип NUMERIC для корректного сравнения чисел, иначе сравнение будет лексикографическим (строковым).
Фильтрация по нескольким полям одновременно
Если нужно фильтровать по нескольким полям, например, цена > 1000 и бренд = 'Nike', используем массив условий с оператором relation:
$args = [
'post_type' => 'product',
'meta_query' => [
'relation' => 'AND',
[
'key' => 'product_price',
'value' => 1000,
'compare' => '>',
'type' => 'NUMERIC'
],
[
'key' => 'product_brand',
'value' => 'Nike',
'compare' => '='
]
]
];
$query = new WP_Query($args);
Фильтрация по полям сложных типов — галерея, повторители, селекты с несколькими значениями
ACF позволяет создавать сложные поля, например, повторители (Repeater), галереи, или поля с несколькими выбранными значениями (checkbox, multi-select). Фильтрация по таким полям требует особого подхода.
Фильтрация по полю с несколькими значениями (checkbox, multi-select)
Значения таких полей хранятся в postmeta в сериализованном виде или через несколько записей с одинаковым ключом. Для простоты лучше использовать LIKE в запросах, например, чтобы найти, содержит ли поле определённое значение.
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'product_features',
'value' => 'waterproof',
'compare' => 'LIKE'
]
]
];
$query = new WP_Query($args);
Такой запрос найдет все записи, где в поле product_features содержится слово 'waterproof'.
Фильтрация по повторителям ACF
Повторители ACF хранятся в виде метаданных с ключами формата repeater_field_0_subfield, где индекс ведется от 0. Чтобы фильтровать по повторителям, нужно знать структуру ключей и писать несколько условий с разными индексами.
Пример: фильтрация товаров, где в повторителе specifications есть значение 'Bluetooth' в подполе feature:
$meta_query = ['relation' => 'OR'];
for ($i = 0; $i < 5; $i++) {
$meta_query[] = [
'key' => 'specifications_' . $i . '_feature',
'value' => 'Bluetooth',
'compare' => 'LIKE'
];
}
$args = [
'post_type' => 'product',
'meta_query' => $meta_query
];
$query = new WP_Query($args);
Здесь мы перебираем первые 5 элементов повторителя. Для большего количества нужно увеличить цикл. Это не самый красивый способ, но пока стандарт WordPress не позволяет фильтровать глубже.
Оптимизация запросов с фильтрацией ACF для больших сайтов
Фильтрация по метаданным — достаточно ресурсоемкая операция, особенно при использовании LIKE и больших объемах данных. Для оптимизации можно:
- Использовать индексы в базе данных для полей, по которым часто фильтруете.
- Кэшировать результаты запросов с помощью Transients API или внешних систем кэширования.
- Ограничивать количество результатов с помощью пагинации.
- Для сложных фильтров рассмотреть использование плагинов, оптимизирующих мета-запросы, например, Clearfy Pro, который улучшает работу с базой.
Пример создания функции фильтрации записей по ACF с использованием WPCoding префикса
Для удобства и поддержки проекта создадим функцию с префиксом wpcoding_, которая возвращает WP_Query с фильтром по произвольному полю ACF:
function wpcoding_get_posts_by_acf_field($post_type, $field_key, $value, $compare = '=', $type = 'CHAR', $relation = 'AND') {
$args = [
'post_type' => $post_type,
'meta_query' => [
'relation' => $relation,
[
'key' => $field_key,
'value' => $value,
'compare' => $compare,
'type' => $type
]
]
];
return new WP_Query($args);
}
// Использование:
$query = wpcoding_get_posts_by_acf_field('product', 'product_price', 1000, '>', 'NUMERIC');
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
echo get_the_title() . '<br>';
}
wp_reset_postdata();
}
Заключение по теме фильтрации ACF в WP_Query
Фильтрация записей WordPress по полям ACF с помощью WP_Query — мощный инструмент для создания гибких и динамичных сайтов. Важно правильно указывать параметры meta_query и учитывать типы полей, чтобы получить корректные результаты и избежать проблем с производительностью.
Для разработки и оптимизации таких запросов полезно тестировать различные варианты и использовать вспомогательные плагины, например, WPRemark для комментариев или кэширования.
Используйте приведенные примеры кода как основу для своих проектов, адаптируя под конкретные задачи и типы полей ACF.