Содержание статьи
Рекомендуется использовать встроенную выборку записей только при отсутствии кастомной логики отображения. Иначе получите проблемы с производительностью, дублирующимся контентом и непредсказуемым поведением в пагинации. Это не шутка – автоматизация иногда выстреливает в ногу.
$args = [
\'post_type\' => \'product\',
\'meta_key\' => \'stock\',
\'meta_value\' => \'1\',
\'posts_per_page\' => 10
];
$products = new WP_Query($args);
while ($products->have_posts()) {
$products->the_post();
the_title();
}
Главный недостаток – ограниченность параметров и отсутствие нативной логики обработки нестандартных типов. Да, можно подключить фильтры. Да, можно переопределить шаблон. Но на выходе получится костыль.
Внимание! Не используйте встроенный механизм выборки, если планируется использовать нестандартные таксономии, мета-запросы или комбинированные условия.
Удобство для новичков? Безусловно. Подходит для MVP, прототипов или лендингов на 3 блока. Настоящие проекты требуют контроля. Контроль невозможен в окружении, где код спрятан за абстракцией редактора.
Хороший способ: соединить ручной запрос и блок-контейнер через render_callback
в register_block_type
. Тогда будет и внешний вид, и логика, и предсказуемость.
Нет пагинации, только бесконечная прокрутка или AJAX? Проблема. Нет поддержки вложенных блоков без плясок с шаблонами? Еще одна.
Важно помнить: автоматические механизмы не заменяют понимание архитектуры CMS. Они ее маскируют.
Используйте встроенные блоки только как временное решение или в контенте, где не требуется точная логика. В остальных случаях – пишите руками. Быстрее, надежнее, проще поддерживать.
Query Loop в WordPress: плюсы и минусы функции
Однако как только возникает необходимость в произвольных условиях, связях между типами данных или множественных параметрах запроса – начинаются проблемы. Например, вы не можете просто так объединить условия по произвольным полям и при этом применить пагинацию. Под капотом – обычный WP_Query
, но интерфейс ограничивает свободу.
Внимание! Ограниченная кастомизация шаблонов делает его непригодным для уникальных дизайнов. Без написания собственного блока или фильтра – не обойтись.
Вынос логики фильтрации за пределы редактора невозможен без дополнительного кода. Нет возможности использовать сторонние библиотеки фильтрации без вмешательства в шаблонную структуру. Пример:
function filter_posts_by_meta( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( isset( $_GET[\'level\'] ) ) {
$query->set( \'meta_key\', \'difficulty\' );
$query->set( \'meta_value\', sanitize_text_field( $_GET[\'level\'] ) );
}
}
add_action( \'pre_get_posts\', \'filter_posts_by_meta\' );
Преимущество – быстрый старт. Можно собрать сетку из записей за пару минут. Поддержка кастомных таксономий есть. Структура адаптируется под тему. Но всё это только пока не начинается реальная задача.
Стилизация блоков затруднена. Классы оберток генерируются автоматически, переопределять их – сложно. В результате – необходимость писать нестандартный CSS или полностью менять шаблон.
Важно помнить: при разработке темы с нуля лучше отказаться от встроенного конструктора и использовать собственные шаблоны на базе PHP.
Использование динамических данных ограничено. Нельзя напрямую встраивать пользовательскую логику, например, для условий отображения по времени суток или статусу пользователя. Всё это требует фильтров, хаков и сторонних решений.
Универсальность мнимая. Да, блок работает, но только в пределах, заданных разработчиками ядра. Любое отклонение – боль, костыли и нестабильность.
Выберите блок \»Цикл публикаций\» в редакторе сайта. Не используйте блок, если в теме отсутствует поддержка редактора шаблонов – работать не будет.
Нажмите \»Настроить\», далее \»Фильтр\». Включите отображение конкретного типа: например, events
, portfolio
, products
. Поле «Тип записи» может не отображаться, если тип скрыт от REST API – проверьте \'show_in_rest\' => true
в коде регистрации.
Важно! Если нужный тип не отображается – он не зарегистрирован для интерфейса редактора. Придётся временно включить REST-доступ или использовать внешний плагин для визуальной настройки.
Выберите макет: сетка, список, карусель. Некоторые темы жёстко фиксируют стили – это ограничит гибкость. Работают далеко не все пользовательские поля. Привязка только к основным: заголовок, дата, изображение. Всё остальное – костыли через дополнительный CSS или фильтры PHP.
Для фильтрации по произвольным полям и таксономиям штатный интерфейс бесполезен. Используйте надстройки:
- Block Visibility
- WP Grid Builder (частично совместим)
- Custom Post Type UI + ACF + Block-based Theme
Максимум, чего можно добиться без кода – выбор конкретного поста, типа или метки. Всё остальное требует JavaScript-хаков или шаблонов в дочерней теме.
Помните! Без доступа к коду вы ограничены только тем, что позволяет тема и интерфейс редактора. Никакие плагины не расширят функциональность выше базовой, если тема этого не допускает.
Для настройки сортировки выберите \»Порядок\». Здесь часто встречаются ошибки: некоторые темы и редакторы не учитывают пользовательские аргументы, вроде meta_key
и orderby
.
Для подстановки пользовательских иконок или структур – только через блоки шаблонов. Некоторые блоки не рендерятся на фронтенде из-за отсутствия поддержки темы. Проверяйте результат в режиме предпросмотра и на мобильных.
Хотите гибкость? Забудьте о no-code. Визуальные настройки подойдут лишь для самых простых задач. Всё остальное – через код или кастомные блоки.
Ограничения Query Loop при работе с таксономиями и пользовательскими полями
Сразу: для фильтрации по нескольким таксономиям с условиями AND используется \'tax_query\' => array( \'relation\' => \'AND\', ... )
, но в стандартном редакторе блоков этого не реализовать. Визуальный интерфейс позволяет только базовые выборки – по одной таксономии, без вложенных условий. Хотите что-то сложнее? Придётся писать код вручную или использовать сторонние расширения.
Фильтрация по мета-полям? Только по одному ключу и значению. Указать массив условий, типа \'meta_query\' => array( \'relation\' => \'OR\', ... )
, нельзя. Блок не поддерживает множественные или вложенные логические операторы. И самое неприятное – невозможно указать тип сравнения (например, BETWEEN
, LIKE
или EXISTS
). Только строгое равенство.
Внимание! Невозможно отфильтровать записи по значению произвольного поля, если оно не сохранено через стандартные API. Пользовательские поля, добавленные через сторонние плагины, могут быть недоступны.
Сортировка? Ограничена. Нельзя сортировать по произвольному полю, если оно не является числовым. Даже если вы явно указываете \'orderby\' => \'meta_value_num\'
, редактор блоков не пропустит настройку. А значит – забываем про сортировку по цене, рейтингу, весу и т.п.
Нет поддержки вложенных условий с одновременной фильтрацией по таксономии и мета-полям. Пример: выбрать все посты с категорией \»Акции\» и полем discount > 20
невозможно средствами стандартного блока. Решение – кастомный WP_Query в шаблоне или создание кастомного REST-запроса через JavaScript.
Важно помнить: если вы используете произвольные поля с префиксами (например, ACF добавляет
_
к системным полям), редактор их не видит. Вы не сможете использовать их в выборке без дополнительных фильтров.
Фильтрация по пользовательским таксономиям работает нестабильно в связке с lazy loading. Некоторые записи не подгружаются, если они находятся в дочерних терминах. Придётся использовать \'include_children\' => true
вручную – в блоке эта настройка недоступна.
Автосохранение условий не работает: при смене категории или поля, блок перезаписывает предыдущую конфигурацию. Для проектов с динамическими фильтрами это катастрофа.
Сравнение производительности Query Loop и кастомных WP_Query запросов в шаблонах
Пример: при использовании блока по умолчанию, под капотом вызывается не просто выборка постов, а целая обвязка – фильтры, разметка, обработчики условий, интернационализация. Это стоит процессорного времени.
Важно: при использовании блочной версии, вы не контролируете кэширование. А значит, при каждом запросе к странице база данных работает заново, даже если результат тот же.
Сравним лоб в лоб. Первый вариант – ручной подход:
$args = [
\'post_type\' => \'post\',
\'posts_per_page\' => 5,
\'no_found_rows\' => true,
\'update_post_meta_cache\' => false,
\'update_post_term_cache\' => false
];
$custom = new WP_Query($args);
while ($custom->have_posts()) {
$custom->the_post();
echo \'<h2>\' . get_the_title() . \'</h2>\';
}
wp_reset_postdata();
Или блок, где всё то же, но под капотом выполняется больше PHP-кода, особенно в редакторе. Это замедляет загрузку админки. На фронте – больше обёрток, хуже индексируется, сложнее оптимизируется.
На слабом хостинге разница может быть до 400 мс на 10 запросах. Это критично. При масштабировании – смертельно.
Внимание! Автоматический механизм не освобождает от ответственности: если вы не следите за количеством блоков на странице, всё полетит в тартарары.
Также: кастомный код проще профилировать. Включили SAVEQUERIES
, посмотрели $wpdb->queries
– и всё видно. А вот с блоками? Никакой прозрачности. Только через дебаг и костыли.