В WordPress для изменения основного запроса и любых дополнительных запросов WP_Query существует мощный хук pre_get_posts. Он позволяет динамически изменять параметры запросов до их выполнения. Это особенно полезно, если нужно фильтровать, сортировать или ограничивать вывод постов без изменения шаблонных файлов.
Что такое хук pre_get_posts и зачем он нужен
Хук pre_get_posts вызывается непосредственно перед выполнением SQL-запроса, формируемого классом WP_Query. С помощью него можно изменить аргументы запроса, например, добавить дополнительные условия фильтрации, изменить порядок сортировки, исключить определённые категории и т.д.
Этот хук часто используют для кастомизации главной страницы, архивов, поисковой выдачи и любых других запросов, не затрагивая при этом ядро WordPress и не создавая собственные запросы вручную. Благодаря этому сайт остаётся более стабильным и гибким.
Важно помнить, что pre_get_posts срабатывает для ВСЕХ запросов, поэтому необходимо корректно фильтровать, к каким именно запросам применять изменения, чтобы не нарушить работу административной панели и плагинов.
Основные параметры и применение хука pre_get_posts
Для работы с хуком нужно добавить функцию-обработчик в файл functions.php или свой плагин. В функцию передаётся объект WP_Query, с которым можно работать как с любым другим объектом WordPress.
Типичный пример для изменения главной страницы и категории выглядит так:
function wpdo_modify_main_query(\WP_Query $query) {
// Выполняем только в фронтенде и для основного запроса
if ( !is_admin() && $query->is_main_query() ) {
// Условие для главной страницы
if ( $query->is_home() ) {
// Показываем только 5 последних постов из категории с ID 3
$query->set('cat', 3);
$query->set('posts_per_page', 5);
}
// Условие для архива рубрики "Новости"
if ( $query->is_category('novosti') ) {
// Исключаем посты с меткой "скрыть"
$tax_query = array(
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => 'skryt',
'operator' => 'NOT IN'
)
);
$query->set('tax_query', $tax_query);
}
}
}
add_action('pre_get_posts', 'wpdo_modify_main_query');
В этом примере мы ограничиваем количество постов на главной странице и фильтруем архив категории, исключая определённые теги.
Использование pre_get_posts для пользовательских типов записей и таксономий
Хук отлично подходит для кастомных типов записей (Custom Post Types) и таксономий. Допустим, у вас есть тип записи portfolio и таксономия project_type, и нужно изменить вывод портфолио в зависимости от типа проекта.
Пример кода для фильтрации портфолио по определённой таксономии:
function wpdo_filter_portfolio_by_project_type(\WP_Query $query) {
if ( !is_admin() && $query->is_main_query() && is_post_type_archive('portfolio') ) {
// Задаём условие: показывать только проекты с таксономией "web-design"
$tax_query = array(
array(
'taxonomy' => 'project_type',
'field' => 'slug',
'terms' => 'web-design',
),
);
$query->set('tax_query', $tax_query);
// Сортируем по дате публикации
$query->set('orderby', 'date');
$query->set('order', 'DESC');
}
}
add_action('pre_get_posts', 'wpdo_filter_portfolio_by_project_type');
Такой подход поможет вывести только нужные записи без создания дополнительных запросов и без изменения шаблонов.
Как избежать ошибок и конфликтов при использовании pre_get_posts
Частая ошибка — применение изменений ко всем запросам без фильтрации. Это может привести к проблемам в админке, виджетах, плагинах и даже к некорректному отображению страниц.
Рекомендации:
- Всегда проверяйте
is_admin()> и$query->is_main_query(). В админке обычно менять запросы не нужно. - Используйте условные теги WordPress (
is_home(),is_category(),is_post_type_archive()и др.) для точного определения, где менять запрос. - Если нужно изменить дополнительные запросы, убедитесь, что вы не ломаете логику других компонентов.
- Тестируйте изменения на локальной среде и используйте отладочные инструменты, например, плагин Query Monitor.
Пример фильтрации поиска WordPress с помощью pre_get_posts
Очень частый запрос — изменить поведение поиска. Например, исключить из результатов страницы и показывать только записи определённого типа.
function wpdo_filter_search_results(\WP_Query $query) {
if ( $query->is_search() && !is_admin() && $query->is_main_query() ) {
// Показывать только записи типа "post"
$query->set('post_type', 'post');
// Исключить записи из категории с ID 10
$query->set('cat', '-10');
}
}
add_action('pre_get_posts', 'wpdo_filter_search_results');
Этот код сделает поиск более релевантным и не позволит показывать ненужные типы записей.
Полезные плагины для работы с запросами и фильтрацией в WordPress
Хотя pre_get_posts — мощный инструмент, для удобства и визуальной настройки запросов можно использовать плагины:
- Query Monitor — отладчик запросов, позволяет видеть текущие WP_Query и SQL-запросы.
- Clearfy Pro — оптимизация и управление функционалом, в том числе запросами.
- WPRemark — продвинутое управление комментариями и фильтрами.
Использование этих инструментов вместе с pre_get_posts позволит вам создавать гибкие и производительные решения без лишних сложностей.
Заключение по работе с pre_get_posts
Хук pre_get_posts — незаменимый инструмент для разработчиков WordPress, позволяющий контролировать практически любой запрос на сайте. Он помогает упростить логику вывода контента, повысить производительность и улучшить пользовательский опыт.
Помните о необходимости точного таргетинга запросов и тестировании всех изменений. Используйте условные теги и всегда проверяйте, что изменения применяются только там, где нужно. Такой подход защитит сайт от неожиданных ошибок и сделает код более поддерживаемым.