Все модификации основного цикла легко и просто делаются хуком pre_get_posts, если точнее, вы можете сделать, например, вот что:
Исключить посты из определённой рубрики,
Увеличить или уменьшить количество постов, отображаемых для определённого типа записи
Исключить страницы из результатов поиска на сайте,
Вывести посты в поиске только после определённой даты,
Сортировать посты в определённой рубрике по количеству комментариев, а не по дате
- Разберёмся, как с этим работать.
- Пример 1. Как исключить вывод постов из определённой рубрики
- Пример 2. Изменение количества постов на странице для страницы архивов типа записи
- Пример 3. Исключить тип записи «Страницы» из результатов поиска на сайте
- Пример 4. Выводим в результатах поиска только посты, опубликованные после определённой даты
- Пример 5. Меняем сортировку записей в рубрике по количеству комментариев
Разберёмся, как с этим работать.
Прежде всего нужно настроиться на определённый цикл! Как правильно ставить условия #
Важно понимать – хук pre_get_posts срабатывает для всех-всех-всех циклов на вашем сайте, даже для тех, которые находятся в админке. Поэтому при помощи условий и условных тегов нам нужно настроиться на определённый цикл.
Например, если мы хотим изменить только основной цикл на страницах категорий, то мы должны:
использовать is_admin() для проверки того, что мы находимся не в админке,
использовать $query->is_main_query(), чтобы приконнектиться только к основному циклу, а не к дополнительному,
is_category() для проверки нахождения на странице архива рубрик.
add_action( 'pre_get_posts', 'true_modify_category_pages_loop' );
function true_modify_category_pages_loop( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
// не админка
// и основной цикл страницы
if ( is_category() ) {
// страница архива рубрик
// например установим 15 записей на странице
$query->set( 'posts_per_page', 15 );
}
}
}
В качестве $query->set() мы используем любые параметры WP_Query. Только не забывайте, что использование параметра offset сломает вам пагинацию.
Также по поводу условий не будет лишним упомянуть – так как pre_get_posts запускается перед непосредственно WP_Query(), то некоторые условные теги, которые зависят от этого класса, могут не работать. Например is_front_page() работать не будет, но зато будет работать is_home(). В таком случае можете прочекать, что находится в переменной $query, передаваемой в хук.
Пример 1. Как исключить вывод постов из определённой рубрики
Например в примере ниже на основной странице блога мы исключаем все посты, которые содержатся в рубрике с ID=152.
add_action( 'pre_get_posts', 'true_exclude_posts_from_cat' );
function true_exclude_posts_from_cat( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set( 'category__not_in', array( 152 ) );
}
}
Пример 2. Изменение количества постов на странице для страницы архивов типа записи
Предположим, что у вас зарегистрирован тип записи, например events для каких-либо событий. И при выводе страницы со всеми событиями вы бы хотели, чтобы на ней отображалось нестандартное число постов, скажем 25 событий за раз.
Это тоже можно легко сделать при помощи pre_get_posts.
Для проверки того, что мы находимся на странице архивов типа записи я использовал условный тег is_post_type_archive().
add_action( 'pre_get_posts', 'true_event_posts_per_page' );
function true_event_posts_per_page( $query ) {
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'event' ) ) {
$query->set( 'posts_per_page', 25 );
}
}
Пример 3. Исключить тип записи «Страницы» из результатов поиска на сайте
По умолчанию, когда вы используете поиск на своём сайте WordPress, то в нём отображаются не только записи, но и страницы. Так вот – вы можете исключить их оттуда при помощи того же самого pre_get_posts. Вот так:
add_action( 'pre_get_posts', 'true_exclude_pages_from_search' );
function true_exclude_pages_from_search( $query ) {
// не админка и основной цикл
if ( ! is_admin() && $query->is_main_query() ) {
// страница поиска
if ( $query->is_search ) {
$query->set( 'post_type', 'post' );
}
}
}
Пример 4. Выводим в результатах поиска только посты, опубликованные после определённой даты
Для достижения этой цели воспользуемся date_query.
add_action( 'pre_get_posts', 'true_posts_in_search_after_date' );
function true_posts_in_search_after_date( $query ) {
// условия
if ( ! is_admin() && $query->is_main_query() && $query->is_search ) {
$query->set( 'date_query', array(
array(
'after' => 'May 17, 2021',
)
) );
}
}
Пример 5. Меняем сортировку записей в рубрике по количеству комментариев
add_action( 'pre_get_posts', 'true_modify_category_pages_loop' );
function true_modify_category_pages_loop( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
// не админка и основной цикл страницы
if ( is_category( 'wordpress' ) ) {
// страница архива рубрики с ярлыком "wordpress"
// меняем сортировку
$query->set( 'orderby', 'comment_count' );
$query->set( 'order', 'DESC' ); // DESC - сначала посты, где больше комментов
}
}
}