Хук pre_get_posts
в WordPress позволяет изменять объект WP_Query
перед его выполнением. Этот мощный инструмент помогает разработчикам настроить запросы в различных контекстах, например, изменить количество постов на странице, включить пользовательские типы записей или исключить определённые записи из результатов поиска.
do_action_ref_array( ‘pre_get_posts’, WP_Query $query )
Хук pre_get_posts
срабатывает после того, как объект WP_Query
был создан, но до выполнения самого запроса. Это идеальное место для модификации таких параметров запроса, как posts_per_page
, post_type
или любых других параметров, передаваемых в запрос.
Важно помнить, что объект $query
передается по ссылке, и это значит, что любые изменения, внесённые в объект внутри функции, непосредственно изменяют оригинальный объект WP_Query
.
Ключевые моменты:
- При использовании условных тегов, таких как
is_main_query()
, убедитесь, что вы вызываете эти методы на объекте$query
, так как они работают с контекстом текущего запроса, а не с глобальным объектом$wp_query
. - Не рекомендуется изменять глобальный запрос за пределами основного цикла или в админ-панели.
Параметры
$query
: Это экземпляр объектаWP_Query
, который содержит параметры запроса. Вы можете изменить объект$query
, чтобы настроить, как WordPress будет извлекать записи.
Как правильно нацелиться на нужный запрос
Хук pre_get_posts
срабатывает для каждого запроса, включая основной запрос, дополнительные запросы и запросы в админ-панели. Поэтому важно точно указать, какой запрос нужно изменить. Используйте условные теги, такие как $query->is_main_query()
, чтобы ваши изменения касались только нужного запроса.
Пример использования:
function change_main_query_for_category($query) {
if ( ! is_admin() && $query->is_main_query() && is_category() ) {
// Изменяем параметры для основного запроса на странице категорий
$query->set('posts_per_page', 10); // Показываем 10 записей
}
}
add_action('pre_get_posts', 'change_main_query_for_category');
В этом примере изменения будут применяться только к основному запросу на страницах категорий, и ничего не изменится в админ-панели.
Работа с условными функциями
Так как хук pre_get_posts
срабатывает до того, как объект WP_Query
полностью будет обработан, не все условные функции, такие как is_front_page()
, будут работать. Вместо них следует использовать свойства объекта $query
, такие как $query->is_home
или $query->is_search
.
Пример корректного использования:
function modify_query_for_search($query) {
if ( ! is_admin() && $query->is_main_query() && $query->is_search ) {
// Изменяем параметры для запроса поиска
$query->set('post_type', array('post', 'movie')); // Включаем кастомный тип записи 'movie'
}
}
add_action('pre_get_posts', 'modify_query_for_search');
Отступы и пагинация
Если вы используете параметр offset
в запросе, это может нарушить пагинацию. Чтобы избежать таких проблем, важно правильно настроить отступ для всех страниц пагинации, основываясь на первоначальном отступе.
Пример использования offset
и пагинации:
function modify_query_with_offset($query) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set('offset', 5); // Начать с 5-й записи
}
}
add_action('pre_get_posts', 'modify_query_with_offset');
Пример 1. Включение кастомного типа записи в поиск
Если вы хотите, чтобы пользовательский тип записи участвовал в поиске, используйте следующий код:
add_action('pre_get_posts', 'include_custom_post_type_in_search');
function include_custom_post_type_in_search($query) {
if ( ! is_admin() && $query->is_main_query() && $query->is_search ) {
$query->set('post_type', array('post', 'movie')); // Включаем тип 'movie'
}
}
Пример 2. Исключение категорий с главной страницы
В этом примере мы исключаем определённые категории с главной страницы:
add_action('pre_get_posts', 'exclude_categories_from_home');
function exclude_categories_from_home($query) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set('cat', '-1,-1347'); // Исключаем категории с ID 1 и 1347
}
}
Пример 3: Универсальная настройка запросов для произвольного типа записи «event»
Если нужно настраивать запросы для определённого типа записи (например, для событий), можно использовать следующий код, который отфильтровывает события по дате:
function university_adjust_queries($query) {
if ( ! is_admin() && is_post_type_archive( 'event' ) && $query->is_main_query() ) {
$query->set( 'meta_key', 'event_date' );
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'order', 'ASC');
$query->set( 'meta_query', array(
array(
'key' => 'event_date',
'compare' => '>=',
'value' => date('Ymd'),
'type' => 'numeric',
)
) );
}
}
add_action( 'pre_get_posts', 'university_adjust_queries' );
Этот код настроит архивы типа записи event
, сортируя события по дате и показывая только те, что ещё не прошли.
Пример 4: Исключение категорий на главной странице
Если необходимо исключить определённые категории из главной страницы, можно использовать следующий код:
function wpdocs_exclude_category( $query ) {
if ( $query->is_home() && $query->is_main_query() && ! is_admin() ) {
$query->set( 'category_name', 'halloween' );
}
}
add_action( 'pre_get_posts', 'wpdocs_exclude_category' );
Этот код выведет на главной странице только записи из категории halloween
.
Пример 5: Включение произвольного типа записи в результаты поиска
Если вы хотите включить произвольный тип записи в результаты поиска, можно использовать следующий код:
function add_custom_pt( $query ) {
if ( !is_admin() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'post', 'the_custom_pt' ) );
}
}
add_action( 'pre_get_posts', 'add_custom_pt' );
Это добавит произвольный тип записи the_custom_pt
в результаты поиска на сайте.
Пример 6: Исключение постоянных страниц из поиска
Если нужно исключить страницы из результатов поиска, можно использовать этот код:
function search_filter( $query ){
if( ! is_admin() && $query->is_main_query() && $query->is_search ){
$query->set( 'post_type', 'post' );
}
}
add_action( 'pre_get_posts', 'search_filter' );
Это исключит постоянные страницы из результатов поиска, показывая только посты.
Пример 7: Изменение количества выводимых на странице постов
Для изменения количества записей на странице, например, на главной или в архиве произвольного типа записи movie
, можно использовать следующий код:
function hwl_home_pagesize( $query ) {
// Выходим, если это админ-панель или не основной запрос.
if( is_admin() || ! $query->is_main_query() )
return;
if( is_home() ){
// Показываем только 1 пост на главной странице
$query->set( 'posts_per_page', 1 );
}
// Показываем 50 записей, если это архив типа записи 'movie'
if( $query->is_post_type_archive('movie') ){
$query->set( 'posts_per_page', 50 );
}
}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );
Этот код установит, что на главной странице будет отображаться только 1 запись, а в архиве типа записи movie
— 50 записей.
Заключение
Хук pre_get_posts
в WordPress предоставляет огромное количество возможностей для модификации запросов. Используйте его с осторожностью, особенно с условными функциями и при изменении запросов в админ-панели. Правильное использование этого хука позволяет вам гибко настроить вывод записей на сайте, улучшить функциональность поиска и улучшить взаимодействие с пользователем.