Множественные, или вложенные, циклы оказываются полезными для решения самых разнообразных вопросов. К примеру, вы хотите, чтобы в сайдбаре выводились последние добавленные записи. Это можно сделать, добавив дополнительный цикл.
Рассмотрим небольшой пример для уяснения действия вложенных циклов.
<?php rewind_posts(); ?> <?php query_posts('category_name=news&showposts=5'); ?> <?php while (have_posts()) : the_post(); ?> <!-- And then the basic loop continues…. -->
Здесь мы определяем вывод пяти последних записей из рубрики News в специальное поле, расположенное в самом низу страницы.
Возможности вывода информации с вложенными циклами
Наиболее часто вложенные циклы применяются для вывода информации в самом верху страницы блога. Такое использование навеяно различными печатными изданиями, в которых информация размещена так, чтобы сразу же завладеть вниманием читателя. Здесь мы рассмотрим способ, при помощи которого удается реализовать данную возможность у себя в блоге. Первое, с чего стоит начать, это создать цикл, который будет отбирать последние записи из категории Featured. Затем понадобится второй цикл, выполняющий аналогичные действия, но уже для всех имеющихся категорий. После всего этого нам понадобится вложить запрос из первого цикла внутрь собственного объекта запроса. Осуществляется это при помощи вызова объекта WP_Query и вложения его в новый запрос. Объект WP_Query незримо присутствует во многих конструкциях (к примеру, когда вы используете have_posts(), на самом деле вы за этим подразумеваете $wp_query -> have_posts()). Довольно часто взаимодействие с WP_Query осуществляется посредством различных шаблонов и условных тегов.
Вот как все это выглядит в действии:
<?php $featured_query = new WP_Query('category_name=featured&showposts=1'); while ($featured_query->have_posts()) : $featured_query->the_post(); $do_not_duplicate = $post->ID; ?> <!-- Styling for your featured post --> <?php endwhile; ?> <!-- Put whatever you want between the featured post and the normal post listing --> <?php if (have_posts()) : while (have_posts()) : the_post(); if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts); ?> <!-- Your normal loop post styling goes here --> <?php endwhile; else: ?> <p>Some error message or similar.</p> <?php endif; ?>
В первой строке мы загружаем $featured_query с новым запросом цикла WP_Query. Этот цикл задает отображение одной записи из категории Featured. Далее мы переходим в цикл while, который очень похож по своей конструкции на основной цикл. Насколько вы знаете, конструкция have_posts() в основном цикле фактически равносильна записи $wp_query-<have_posts(), однако в данном случае вместо $wp_query используется $featured_query. Это означает, что мы воздействуем на новый объект, отличный от $wp_query, в результате чего $wp_query остается без изменений. В третьей строке мы загружаем идентификатор записи в объект $do_not_duplicate. Основная идея здесь состоит в том, чтобы убрать запись из категории, в которой она расположена, и различных списков, которые могут ее отображать. Далее в коде идет область отображения записи, в которой можно определить различные стилевые характеристики, задать дополнительные поля для вывода изображений и т.д. В целом, мы работаем с обычным основным циклом, в котором содержатся небольшие добавления. На восьмой строке производится сравнение двух идентификаторов: идентификатора записи и идентификатора, хранящегося в $do_not_duplicate. Если они равны, то производится дальнейшее обновление кэша записи, если нет — запись выводится в обычном варианте. Иными словами, запись, которую необходимо вывести вверху, будет выпущена из обработки в основном цикле. После всего этого следует основной цикл, отвечающий за обычный вывод записей.
Иными словами, сначала вы выводите выбранную запись в отдельном цикле. Затем, в регулярном цикле, вы выводите все остальные записи за исключением выбранной, чей идентификатор хранится в $do_not_duplicate.
Применение нескольких вложенных циклов
Теперь мы подошли к самому сложному: использованию нескольких вложенных циклов. В примере, приведенном ниже, будут выбраны три записи, каждая из своей определенной категории, которые затем будут выведены в столбик, друг под другом. Идея взята с обычных сайтов, которые обычно информируют посетителя относительно новых событий или происшествий. Рассмотрим пример:
<?php $featured_query = new WP_Query('category_name=featured&showposts=3'); while ($featured_query->have_posts()) : $featured_query->the_post(); $do_not_duplicate[] = $post->ID ?> <!-- Styling for your featured posts --> <?php endwhile; ?> <!-- Now begins the first column loop --> <?php query_posts('category_name=apples&showposts=10'); ?> <?php while (have_posts()) : the_post(); ?> if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?> <!-- Category Apples post --> <?php endwhile; ?> <!-- Now begins the second column loop --> <?php rewind_posts(); ?> <?php query_posts('category_name=oranges&showposts=10'); ?> <?php while (have_posts()) : the_post(); ?> if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?> <!-- Category Oranges post --> <?php endwhile; ?> <!-- Now begins the third column loop --> <?php rewind_posts(); ?> <?php query_posts('category_name=lemons&showposts=10'); ?> <?php while (have_posts()) : the_post(); ?> if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?> <!-- Category Lemons post --> <?php endwhile; ?>
Этот код во многом повторяет предыдущий пример, однако здесь вместо одной записи нам надо вывести сразу три. Их идентификаторы мы заносим в массив $do_not_duplicate[]. Находящиеся в нем идентификаторы будут проверяться в каждом из последующих циклов.
Теперь приведем пример кода с четырьмя циклами, первый из которых выводит на экран выбранные записи, а оставшиеся три служат для отображения последних записей в трех категориях.
<div id="featured"> <?php $featured_query = new WP_Query('category_name=featured&showposts=3'); while ($featured_query->have_posts()) : $featured_query->the_post(); $do_not_duplicate[] = $post->ID ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h2> <?php the_excerpt(); ?> </div> <?php endwhile; ?> </div> <div> <h2>Latest from <span>Apples</span></h2> <ul> <!-- Now begins the first column loop --> <?php query_posts('category_name=apples&showposts=10'); ?> <?php while (have_posts()) : the_post(); if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?> <li> <h3><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3> <?php the_excerpt(); ?> </li> <?php endwhile; ?> </ul> </div><div> <h2>Latest from <span>Oranges</span></h2> <ul> <!-- Now begins the second column loop --> <?php rewind_posts(); ?> <?php query_posts('category_name=oranges&showposts=10'); ?> <?php while (have_posts()) : the_post(); if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?> <li> <h3><a href="<?php the_permalink(); ?<" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3> <?php the_excerpt(); ?> </li> <?php endwhile; ?> </ul> </div><div> <h2>Latest from <span>Lemons</span></h2> <ul> <!-- Now begins the third column loop --> <?php rewind_posts(); ?> <?php query_posts('category_name=lemons&showposts=10'); ?> <?php while (have_posts()) : the_post(); if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?> <li> <h3><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3> <?php the_excerpt(); ?> </li> <?php endwhile; ?> </ul> </div>
Естественно, в вашем блоге категории могут обладать другими названиями, поэтому обязательно подкорректируйте код перед его размещением.