В WordPress есть мощный инструмент для изменения основных запросов — хук pre_get_posts. Это событие позволяет вмешиваться в запросы, которые формирует WordPress, и изменять параметры вывода записей до их получения из базы данных. Это особенно полезно, если нужно создавать кастомные фильтры, менять логику вывода на страницах архива, главной или категорий без изменения шаблонов.
Что такое хук pre_get_posts и когда он вызывается
Хук pre_get_posts срабатывает перед выполнением основного SQL-запроса WordPress. В этот момент можно получить объект запроса WP_Query и изменить его свойства, например, типы записей, таксономии, количество записей на страницу, порядок сортировки и многое другое.
Важно понимать, что pre_get_posts вызывается не только для главного запроса, но и для дополнительных запросов, например, в виджетах или в пользовательских WP_Query. Поэтому при работе с этим хуком нужно внимательно фильтровать, к какому именно запросу вы хотите применить изменения.
Выбор главного запроса
Для изменения только главного запроса используйте проверку $query->is_main_query(). Это гарантирует, что вы не сломаете вывод других компонентов сайта.
Пример: вывод только записей определенной категории на главной странице
Предположим, нам нужно, чтобы на главной выводились только записи из категории с ID 7. Для этого добавим функцию с использованием pre_get_posts:
function wphelper_pre_get_posts_filter(\WP_Query $query) {
if ( !is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set('cat', '7'); // ID категории
}
}
add_action('pre_get_posts', 'wphelper_pre_get_posts_filter');
Код проверяет, что запрос не в админке, является главным и относится к главной странице, затем добавляет фильтр по категории.
Пример: исключение определенного типа записей из архива
Если на странице архива нужно исключить записи определенного типа, например, portfolio, то можно сделать так:
function wphelper_exclude_post_type_from_archive(\WP_Query $query) {
if ( !is_admin() && $query->is_main_query() && $query->is_post_type_archive('post') ) {
$query->set('post_type', ['post']);
$query->set('post__not_in', get_posts(['post_type' => 'portfolio', 'fields' => 'ids']));
}
}
add_action('pre_get_posts', 'wphelper_exclude_post_type_from_archive');
Обратите внимание, что для исключения записей мы получаем их ID и передаем в параметр post__not_in.
Фильтрация по пользовательским полям (meta_query) с pre_get_posts
Иногда нужно отфильтровать записи по кастомному полю. Например, вывести только записи, у которых значение поля price больше 1000.
function wphelper_filter_by_meta_price(\WP_Query $query) {
if ( !is_admin() && $query->is_main_query() && is_post_type_archive('product') ) {
$meta_query = [
[
'key' => 'price',
'value' => 1000,
'compare' => '>',
'type' => 'NUMERIC'
]
];
$query->set('meta_query', $meta_query);
}
}
add_action('pre_get_posts', 'wphelper_filter_by_meta_price');
Такой подход позволяет гибко настраивать выборку записей на уровне запроса без создания дополнительных запросов в шаблонах.
Рекомендации и подводные камни при работе с pre_get_posts
1. Всегда фильтруйте запросы: используйте is_main_query() и условия is_home(), is_archive() и т.п., чтобы не влиять на админку и другие WP_Query.
2. Не вызывайте запросы внутри функции: если внутри хука делать новые запросы WP_Query, можно получить рекурсию.
3. Тестируйте изменения: даже небольшие изменения параметров запроса могут повлиять на пагинацию, сортировку и работу плагинов.
Использование плагинов для расширения возможностей pre_get_posts
Для удобства и расширения функционала фильтрации запросов можно использовать плагины. Например, Clearfy Pro предлагает набор оптимизаций, в том числе управление запросами, а WPRemark позволяет фильтровать комментарии и отзывы.
Пример с Clearfy: отключение ненужных запросов для ускорения сайта
Clearfy позволяет отключить некоторые системные запросы и фильтры, что уменьшает нагрузку на базу данных и ускоряет загрузку страниц. Это дополняет подход с pre_get_posts и помогает избежать лишних запросов.
Заключение
Хук pre_get_posts — ключевой инструмент для кастомизации выборки записей в WordPress. С его помощью можно реализовать практически любые фильтры и изменить логику вывода контента без вмешательства в шаблоны. Главное — аккуратно фильтровать запросы и тестировать изменения, чтобы не нарушить работу сайта и не привести к ошибкам.