В этой статье:
Цикл WordPress и дополнительные циклы
функции have_posts(), the_post(), rewind_posts(), query_posts(), wp_reset_postdata()
объект WP_Query
глобальные массивы $wp_query $posts
Цикл WordPress
Цикл WordPress имеет такой вид:
// если есть записи
<?php if (have_posts()) : ?>
// пока есть записи, извлекать по одной записи
<?php while (have_posts()) : the_post(); ?>
<!--обработка ... -->
<?php endwhile; ?>
<?php endif; ?>
Функции have_posts() и the_post() работают с глобальным (global) объектом $wp_query, который вызывается в header блога. При этом формируется и выполняется запрос к базе данных (БД), возвращающий массив записей блога, который затем хранится в этом объекте, а также в глобальном массиве $posts (для обеспечения обратной совместимости).
have_posts() (вызывает $wp_query->have_posts()) проверяет, есть ли еще записи в массиве записей
the_post() (вызывает $wp_query->the_post()) заполняет глобальную переменную $post и все глобальные данные, связанные с текущей извлекаемой записью, и увеличивает счетчик цикла.
Несколько циклов на одной странице
Для того чтобы в случае необходимости выполнить цикл еще раз, нужно "отмотать все назад" с помощью функции
<?php rewind_posts(); ?>
Или можно использовать функцию query_posts(), которая выполняет новый запрос, создает новый массив записей и отматывает назад счетчик цикла:
// 10 последних записей из категории cat1
<?php query_posts('category_name=cat1&posts_per_page=10'); ?>
<?php while (have_posts()) : the_post(); ?>
...
<?php endwhile;?>
Если нужно сохранить (не перезаписывать) результаты исходного запроса, можно создать копию$wp_query или создать новый объект запроса. Вот, например, два цикла: сначала вывод одной записи из рубрики featured и затем вывод последних добавленных записей, исключая первую выведенную запись
<?php $my_query = new WP_Query('category_name=featured&posts_per_page=1');
while ($my_query->have_posts()) : $my_query->the_post();
$do_not_duplicate = $post->ID; ?>
...
<?php endwhile; ?>
...
<?php if (have_posts()) : while (have_posts()) : the_post();
if( $post->ID == $do_not_duplicate ) continue;?>
...
<?php endwhile; endif; ?>
Или вывод нескольких записей в первом цикле:
<?php $my_query = new WP_Query('category_name=featured&posts_per_page=3');
while ($my_query->have_posts()) : $my_query->the_post();
$do_not_duplicate[] = $post->ID ?> // массив id записей
...
<?php endwhile; ?>
...
<?php if (have_posts()) : while (have_posts()) : the_post();
if (in_array($post->ID, $do_not_duplicate)) continue;
?>
...
<?php endwhile; endif; ?>
Можно пойти и другим путем - сразу исключить из запроса записи из массива:
<?php query_posts(array('post__not_in'=>$do_not_duplicate));
if (have_posts()) : while (have_posts()) : the_post();
?>
Вложенные циклы
Цикл внутри основного (по окончании внутреннего цикла продолжается внешний цикл ):
$my_query = new WP_Query( "cat=3" );
if ( $my_query->have_posts() ) {
while ( $my_query->have_posts() ) {
$my_query->the_post();
the_content();
}
}
// Установка некоторых глобальных переменных:
wp_reset_postdata();
Спасибо за подробное объяснение.