Вопрос или проблема
Я использую два цикла на главной странице: один для отображения 3 последних записей, а другой для отображения остальных записей, за исключением первых 3.
Я использую следующий код для pre_get_posts.
function tax_and_offset_homepage( $query ) {
if ( !is_admin() && $query->is_home() && $query->is_main_query() )
$query->set( 'post_type', array( 'post') );
$ppp = get_option( 'posts_per_page' );
//$ppp = 300;
$offset = 3;
if ( !$query->is_paged() ) {
$query->set( 'posts_per_page', $ppp);
$query->set( 'offset', $offset);
}
}
add_action('pre_get_posts','tax_and_offset_homepage');
и следующий код для основного цикла:
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
//
// Содержимое записи здесь
//
} // конец while
} // конец if
?>
но проблема в том, что pre_get_posts можно применить только к одному из 2 циклов. Как мне сделать 2 функции pre_get_posts для двух циклов на одной странице?
Посмотрите на WP_Query
, когда вам нужно пройтись по записям.
<?php
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'post__not_in' => array(),
'order' => 'DESC',
);
$the_query = new WP_Query($args);
// Показать первые 3 записи
while($the_query->have_posts()) { $the_query->the_post();
echo '<h2>'.get_the_title().'</h2>';
// Мы уже показали 3? Тогда прерываем. (счетчик current_post начинается с 0)
if( $the_query->current_post == 2 ) { break; }
}
// Продолжаем цикл с того места, на котором остановились
while($the_query->have_posts()) { $the_query->the_post();
echo '<h2>'.get_the_title().'</h2>';
}
wp_reset_postdata();
?>
Ответ или решение
Для реализации двух циклов на главной странице WordPress, один из которых будет выводить три последних поста, а другой — оставшиеся посты, вы сталкиваетесь с необходимостью использовать хуки WordPress корректно, без конфликтов между запросами. Ваша текущая реализация pre_get_posts
будет действовать только на один из запросов, поэтому необходимо изменить подход к созданию запросов.
Решение проблемы с использованием WP_Query
Вместо того, чтобы полагаться на pre_get_posts
, следует использовать класс WP_Query
, который предоставит вам большую гибкость в управлении несколькими запросами на одной странице.
Код для реализации двух циклов
Вот пример, как можно организовать ваши запросы с помощью WP_Query
:
<?php
// Настроим параметры для запроса первых трёх постов.
$args_latest = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 3,
'order' => 'DESC',
);
// Создаем новый объект WP_Query для последних трех постов.
$latest_query = new WP_Query($args_latest);
// Цикл для вывода первых трех постов.
if ($latest_query->have_posts()) {
echo '<h2>Последние посты:</h2>';
while ($latest_query->have_posts()) {
$latest_query->the_post();
// Здесь выводим контент поста
echo '<h3>' . get_the_title() . '</h3>';
// Можно добавить краткое содержание и ссылку
}
wp_reset_postdata(); // Сброс данных после выполнения первого запроса.
}
// Теперь нам нужно взять все остальные посты, исключая те, что мы только что вывели.
$args_remaining = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1, // Получаем все оставшиеся посты
'offset' => 3, // Смещение на 3 для пропуска уже выведенных постов
'order' => 'DESC',
);
$remaining_query = new WP_Query($args_remaining);
// Цикл для вывода оставшихся постов.
if ($remaining_query->have_posts()) {
echo '<h2>Остальные посты:</h2>';
while ($remaining_query->have_posts()) {
$remaining_query->the_post();
// Здесь выводим контент других постов
echo '<h3>' . get_the_title() . '</h3>';
// Можно добавить краткое содержание и ссылку
}
wp_reset_postdata(); // Сброс данных после выполнения второго запроса.
}
?>
Краткое объяснение кода
- Первый запрос (
$latest_query
): Запрашиваются последние три поста с использованием параметров$args_latest
. Мы выводим их в первом цикле. - Сброс данных поста: После завершения первого цикла, мы используем
wp_reset_postdata()
, чтобы убедиться, что все глобальные переменные поста сброшены перед следующим циклом. - Второй запрос (
$remaining_query
): Переменная$args_remaining
устанавливает смещение на 3, чтобы пропустить уже выведенные посты. Мы получаем все оставшиеся посты и выводим их во втором цикле. - Использование
post_type
: Оба запроса устанавливаютpost_type
какpost
, что указывает на необходимость отображения только типовых постов.
Рекомендации по SEO и производительности
- Кэширование: Рассмотрите возможность кэширования результатов запросов для улучшения производительности, особенно если ваш сайт имеет большой трафик.
- Оптимизация SQL-запросов: Постарайтесь не запрашивать слишком много постов одновременно (например, устанавливая
posts_per_page
в более чем 10), так как это может замедлить работу страницы в зависимости от сложности контента.
Следуя этим рекомендациям, вы сможете успешно реализовать два отдельных цикла на одной странице без конфликтов и с эффективным управлением запросами к базе данных.