Фильтр pre_get_posts — один из самых мощных инструментов в WordPress для изменения параметров запросов, которые WordPress выполняет для вывода постов. Этот фильтр позволяет модифицировать как главный запрос страницы, так и дополнительные WP_Query в теме или плагинах. В этой статье мы подробно рассмотрим, как правильно использовать pre_get_posts, чтобы настроить вывод контента под конкретные задачи.
Что такое фильтр pre_get_posts в WordPress и зачем он нужен
pre_get_posts — это хук, который срабатывает после создания объекта запроса WP_Query, но до выполнения SQL-запроса к базе данных. С его помощью можно изменить параметры запроса, например, типы постов, таксономии, количество выводимых записей и другие аргументы.
Применение фильтра позволяет избежать создания дополнительных WP_Query и использовать стандартные механизмы WordPress для вывода данных, что положительно сказывается на производительности и совместимости.
Частые задачи, решаемые с помощью pre_get_posts:
- Отфильтровать главную страницу, чтобы показывать только определённые типы постов;
- Настроить архивы по категориям, тегам или таксономиям;
- Изменить количество выводимых записей на страницах;
- Исключить определённые посты из вывода;
- Изменить порядок сортировки постов.
Основные правила работы с pre_get_posts
При работе с pre_get_posts важно помнить, что фильтр срабатывает для каждого запроса, в том числе для административных страниц, виджетов и других запросов, не связанных с основным выводом страниц сайта. Поэтому нужно обязательно проверять, какой запрос вы собираетесь изменять.
Самая распространённая проверка — убедиться, что это главный запрос на фронтенде:
function wptemplates_pre_get_posts_filter( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// Далее меняем параметры запроса
}
add_action( 'pre_get_posts', 'wptemplates_pre_get_posts_filter' );
Без такой проверки можно случайно нарушить работу административной части или других функциональных элементов сайта.
Пример 1: Вывод на главной странице только постов типа 'news'
Допустим, у вас есть кастомный тип постов news, и вы хотите на главной странице показывать только новости, а не стандартные записи.
function wptemplates_show_only_news_on_home( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_home() ) {
$query->set( 'post_type', 'news' );
$query->set( 'posts_per_page', 10 );
}
}
add_action( 'pre_get_posts', 'wptemplates_show_only_news_on_home' );
Здесь мы проверяем, что это главный запрос и главная страница, затем меняем тип постов и количество выводимых записей.
Пример 2: Исключение определённых категорий из архива блога
Если нужно исключить из вывода посты определённых категорий, можно сделать так:
function wptemplates_exclude_categories_from_blog( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_home() || $query->is_archive() ) {
// ID категорий, которые нужно исключить
$exclude_cat_ids = array( 5, 12 );
$query->set( 'category__not_in', $exclude_cat_ids );
}
}
add_action( 'pre_get_posts', 'wptemplates_exclude_categories_from_blog' );
В этом примере для главной и архивных страниц исключаются посты из категорий с ID 5 и 12.
Пример 3: Изменение порядка сортировки на странице архива
По умолчанию WordPress сортирует посты по дате публикации. Если нужно изменить порядок, например, сортировать по алфавиту по заголовку, то можно использовать:
function wptemplates_order_archive_by_title( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_archive() ) {
$query->set( 'orderby', 'title' );
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'wptemplates_order_archive_by_title' );
Таким образом, на страницах архивов посты будут отсортированы по названию в алфавитном порядке.
Практические советы по использованию pre_get_posts
1. Всегда проверяйте is_admin() и is_main_query(), чтобы избежать непреднамеренных изменений запросов в админке или второстепенных запросов.
2. Если вы хотите изменить запрос не для главной страницы, а для определённого типа архива, используйте условные теги WordPress, например is_post_type_archive('product') или is_category('news').
3. Для сложных условий комбинируйте несколько проверок и используйте методы объекта WP_Query, например $query->is_search() для поиска.
4. Помните, что некоторые параметры, например posts_per_page, могут быть переопределены настройками в админке, поэтому убедитесь, что ваши изменения не конфликтуют с общими настройками.
Плагины для визуальной настройки запросов с помощью pre_get_posts
Если вы не хотите писать код, существуют плагины, которые позволяют менять параметры запросов через интерфейс:
- Query Wrangler — плагин для создания и управления пользовательскими запросами с визуальным редактором;
- WP Query Builder — удобный инструмент для настройки WP_Query без кода;
- Advanced Custom Fields (ACF) в связке с кастомными запросами можно использовать для более гибкой фильтрации контента.
Тем не менее, для точечного и производительного решения лучше использовать фильтр pre_get_posts напрямую в коде темы или плагина.
Заключение
Фильтр pre_get_posts — это незаменимый инструмент для разработчиков WordPress, который позволяет гибко и эффективно контролировать вывод контента на сайте. Освоив его, вы сможете решать широкий спектр задач по кастомизации запросов, улучшая пользовательский опыт и оптимизируя производительность.