Цикл WordPress — это код, с помощью которого отображается контент на вашем сайте на WordPress.
Возьмем, к примеру, шаблон index.php. В основной теме для блога этот шаблон используется для вывода нескольких записей или же анонса записи на домашней странице сайта, а WordPress цикл помогает это сделать.
Вам пригодятся минимальные знания о цикле, если вы хотите усовершенствовать дизайн своего сайта на WordPress. Даже если вы не знакомы с PHP или HTML, то после прочтения этого поста у вас будут представления о том, как работает цикл WordPress.
Смотрите также:
- Советы для начинающих разработку сайта на WordPress
- Куда вставлять этот код в WordPress? Общая структура файлов темы
- WordPress Codex — ценный помощник разработчика
- О важности кода при разработке WordPress-темы
- О типичных ошибках в разработке под WordPress и о том, как их исправить
Понимание цикла в WordPress
Лучший способ понять принцип работы цикла WordPress — это посмотреть, как он используется в теме WordPress. Поэтому, давайте изначально рассмотрим простой код, а затем и каждую его строку по отдельности, чтоб понять, какую функцию каждая из них выполняет.
Ниже приведен пример самого простого цикла WordPress. Код в используемой вами теме на WordPress для цикла может быть более длинным, но его структура ничем не отличается.
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); // // Post Content here // endwhile; // end while endif; // end if ?>
Если вы хоть немного разбираетесь в PHP, то вышеупомянутый код, скорее всего, будет вам понятен. Но, тем не менее, мы все-таки детально рассмотрим каждую строку кода на случай, если вы абсолютный новичок в этом.
Первым делом мы сообщаем серверу, что мы будем использовать PHP. Открываем функцию PHP следующим образом:
<?php
В следующей строке у нас идет привычная функция проверки «if» с функцией have_posts. Эта функция относится к логической, что означает, что она может быть как правдивой, так и ложной.
Поэтому следующая строка в коде говорит нам следующее, что «Если есть записи, которые должны выводиться – эту строку нужно использовать, если их нет — ничего не делать»:
if ( have_posts() ) :
В следующей строке используется цикл while. Он будет выполняться, если информация «правдива». То есть, если есть записи, которые должны выводиться на сайте, то эта строка должна быть в коде.
Поэтому, если на вашем сайте должны отображаться пять постов на домашней странице, функция while будет отображать данные в цикле пять раз:
while ( have_posts() ) :
Затем мы берем данные со следующей записи, используя функцию the_post. Это позволяет настроить запись и получить любую часть или информацию о посте, включая контент, дату публикации, автора записи, категорию публикации и многое другое:
the_post();
Раз уж мы упомянули нашу запись, мы можем отобразить в ней все, что хотим. Существует более тысячи доступных тэгов, которые могут быть использованы только в цикле WordPress. Например, the_title для вывода заголовка поста, the_content для отображения самого поста, the_category — для категорий и рубрик:
// // Post Content here //
После подтверждения информации, которая должна отображаться на сайте, мы закрываем цикл while:
endwhile; // end while
Затем мы закрываем функцию проверки «if»:
endif; // end if
И закрываем код PHP:
?>
Как видите, если разбить цикл по строчкам, то все становится понятным.
Примеры цикла
В WordPress Codex есть шаблон маленького кода index.php. В коде ниже видно, что в шаблоне index.php упоминается шапка, цикл WordPress, сайдбар и футер:
<?php get_header(); if (have_posts()) : while (have_posts()) : the_post(); the_content(); endwhile; endif; get_sidebar(); get_footer(); ?>
Код для цикла WordPress выглядит немного иначе в большинстве тем WordPress, потому что и отображаемая информация немного другая. Самый лучший способ понять, как цикл работает на практике – это изучить цикл WordPress в разных темах оформления.
Ниже приведен пример кода, который используется для цикла в шаблоне нынешней стандартной темы на WordPress — Twenty Fourteen. Как вы видите, в этой теме используются разные шаблоны для контента, в зависимости от типа поста. Например, стандартный пост будет выводить разную информацию из видео-постов и цитат-постов.
Навигационные линки выводятся после последнего поста, и сообщение отображается для посетителей в случае, если пост был не найден (это осуществляется с помощью шаблона content-none.php).
<?php if ( have_posts() ) : // Start the Loop. while ( have_posts() ) : the_post(); /* * Include the post format-specific template for the content.
you want to * use this in a child theme, then include a file called called content-___.php * (where ___ is the post format) and that will be used instead. */ get_template_part( 'content', get_post_format() ); endwhile; // Previous/next post navigation. twentyfourteen_paging_nav(); else : // If no content, include the "No posts found" template. get_template_part( 'content', 'none' ); endif; ?>
Цикл легче использовать в темах TwentyFourteen и Twenty Thirteen, потому что код для вывода контента и мета-информации находится в разных шаблонах. Более практично структурировать код для тем, которые поддерживают форматы постов.
Если проанализировать популярную тему Twenty Twelve, то можно заметить, что цикл требует наличия других файлов шаблона. Но большинство кода остается в шаблоне цикла — index.php.
<?php if ( have_posts() ) : ?> <?php /* Start the Loop */ ?> <?php while ( have_posts() ) : the_post(); ?> <?php get_template_part( 'content', get_post_format() ); ?> <?php endwhile; ?> <?php twentytwelve_content_nav( 'nav-below' ); ?> <?php else : ?> <article id="post-0" class="post no-results not-found"> <?php if ( current_user_can( 'edit_posts' ) ) : // Show a different message to a logged-in user who can add posts.
?> <header class="entry-header"> <h1 class="entry-title"><?php _e( 'No posts to display', 'twentytwelve' ); ?></h1> </header> <div class="entry-content"> <p><?php printf( __( 'Ready to publish your first post? <a href="%s">Get started here</a>.', 'twentytwelve' ), admin_url( 'post-new.php' ) ); ?></p> </div><!-- .entry-content --> <?php else : // Show the default message to everyone else. ?> <header class="entry-header"> <h1 class="entry-title"><?php _e( 'Nothing Found', 'twentytwelve' ); ?></h1> </header> <div class="entry-content"> <p><?php _e( 'Apologies, but no results were found. Perhaps searching will help find a related post.', 'twentytwelve' ); ?></p> <?php get_search_form(); ?> </div><!-- .entry-content --> <?php endif; // end current_user_can() check ?> </article><!-- #post-0 --> <?php endif; // end have_posts() check ?>
Лучше всего запомнить принцип кодирования «Не повторяйте самостоятельно!». Сокращая количество повторений, вы можете создать более компактные темы, и вам будет легче их изменять.
hostenko.com
Стандартный цикл wordpress (index.php, category.php, tag.php, архивы)
<?php if (have_posts()) : ?> <?php while (have_posts() ) : the_post(); ?> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <?php endwhile; ?> <?php endif; ?>
Цикл на основе query_posts()
<?php global $query_string; // параметры базового запроса query_posts($query_string.'&cat=-6,-9&order=ASC&posts_per_page=20'); // базовый запрос + свои параметры ?> [СТАНДАРТНЫЙ ЦИКЛ WORDPRESS] <?php wp_reset_query();// сброс запроса?>
Цикл на основе WP_Query()
<?php $query = new WP_Query( 'cat=9&nopaging=1' );// указываем категорию 9 и выключаем разбиение на страницы (пагинацию) ?> <?php if ($query ->have_posts()) : ?> <?php while ($query->have_posts() ) : $query->the_post(); ?> <h2><a href="<?php the_permalink(); ?>"> <?php the_title(); ?></a></h2> <?php endwhile; ?> <?php endif; ?> <?php wp_reset_postdata(); // сбрасываем переменную $post ?>
Цикл на основе get_posts()
<?php global $post; $args = array( 'posts_per_page' => 5, 'offset'=> 0, 'category' => 48 ); $myposts = get_posts( $args ); foreach( $myposts as $post ) : setup_postdata($post); ?> <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(thumbnail); ?><?php the_title(); ?></a> <?php endforeach; ?> <?php wp_reset_postdata() ?>
Где и какой из 3-х вариантов циклов использовать:
- query_posts() — если нужно изменить/подправить стандартный вывод записей на страницах WordPress. Можно использовать 1 раз на странице;
- get_posts() — если нужно вывести записи из Базы Данных. Можно использовать сколько угодно раз на странице;
- Класс WP_Query() — во всех других случаях когда не подошли query_posts() и get_posts().
Инфографика по данной теме
И еще раз тезисно:
query_posts — основной (базовый) запрос wordpress, влияет в каком месте (запись, категория, поиск и т.д.) сайта мы находимся. Если необходимо незначительно скорректировать используем query_posts.
Если нужно создать какой-либо масштабный запрос, используем WP_Query — это независимый полноценный запрос.
get_posts является легковесной служебной функцией для создания выборки постов.
Дальнейшая тема для изучения — глобальные переменные.
opttour.ru
Что такое цикл WordPress
Цикл WordPress это постоянно повторяющейся действие, которое позволяет обрабатывать массив информации и выводить нужную информацию на текущей странице поста, а также формировать страницу поста в соответствии с критериями указанными внутри этого цикла.
Любой код, имеется в виду HTML и PHP, размещенный внутри цикла будет повторяться для каждой записи. Например, специальный тег comments_link() который выводит ссылку на показ формы комментария , применяется внутри цикла WordPress и будет повторяться для каждой записи.
Классический пример цикла, в файле index.php. Данный файл отображает только содержимое каждого сообщения, в соответствии с условиями, использованными для подготовки Цикла. Этот пример показывает, как мало нужно для работы Цикла.
<?php get_header(); if (have_posts()) : while (have_posts()) : the_post(); the_content(); endwhile; endif; get_sidebar(); get_footer(); >
Например, в файле content.php есть цикл, в котором последовательно прописаны теги, выводящие заголовок статьи, содержание статьи, комментарии статьи. Следовательно, каждая статья будет начинаться с заголовка, потом содержание, потом комментарии. Но стоит поменять местами теги выводящие комментарии и содержания, все статьи будут начинаться с заголовка, потом комментарии, потом содержание.
В WordPress возможны четыре построения циклов для вывода записей:
- Стандартный цикл WordPress;
- Цикл WordPress на основе query_posts();
- Цикл WordPress на основе Wp_Query();
- Цикл WordPress на основе get_posts().
Стандартный цикл WordPress
Стандартный цикл WordPress это цикл с предусловием (оператор PHP while). В стандартном цикле мы не указываем данные для выборки записей. При входе в цикл вычисляется условие и, если его значение отлично от нуля, выполняется тело цикла. Поэтому, стандартный цикл сразу начинаем с if (have_posts()), и если запись присутствует, то тело цикла выполняется до его окончания, а данные после обработки выводятся на экран.
Пример стандартного цикла
<?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="page-title"><?php the_title(); ?></h2> <?php edit_post_link(__( 'Edit', 'zeeTasty_lang' )); ?> <div class="entry clearfix"> <?php the_post_thumbnail('medium', array('class' => 'alignleft')); ?> <?php the_content(); ?> </div> <?php wp_link_pages(); ?> </div> <?php endwhile; ?> <?php endif; ?>
Более точно, это работает так:
После того как WordPress загрузил заголовок блога и передал его в шаблон, переходим к Циклу записей. Функция have_posts() вызывает переменную $wp_query->have_posts(), которая проверяет счетчик цикла на наличие любых записей во всем массиве записей. Также функция the_post() вызывает переменную $wp_query->the_post(), которая увеличивает счетчик цикла и устанавливает глобальную переменную $post, аналогично всем данным записей. Выполнив цикл один раз, функция have_posts() вернет false(нет) и цикл закончится.
Цикл WordPress на основе query_posts()
Функция query_posts() позволяет изменить базовый запрос и вывести нужный нам вариант записей. query_posts() не предназначена для создания нового цикла, а только для изменения стандартного цикла.
Другими словами, цикл WordPress на основе query_posts() это стандартный цикл WordPress с измененными (дополненными) параметрами запроса. Например, функцией query_posts() можно вырезать отдельные категории или изменить порядок сортировки или убрать отдельные статьи или изменить количество записей.
Важно: при вызове query_posts создается новый объект wp_query, который затем будет использоваться в цикле, поэтому функция query_posts должна располагаться перед стандартным циклом WordPress. При таком расположении WordPress перестает учитывать параметры записи, полученные из URL, и цикл выполняется с параметрами запроса query_posts().
Пример цикла на основе query_posts()
<?php query_posts($args); //$args - параметры запроса // [Стандартный Цикл WordPress] wp_reset_query(); // сброс запроса ?>
Еще пример
<?php // Запрос -The Query query_posts( $args ); // The Loop-стандартный цикл while ( have_posts() ) : the_post(); echo '<li>'; the_title(); echo '</li>'; endwhile; // Reset Query- сброс (остановка) guery wp_reset_query(); ?>
Здесь стоит поговорить, про параметры функции query_posts(). Находится query_posts() в файле wp-includes/query.php.
Цикл WordPress на основе WP_Query()
Цикл WordPress на основе класса WP_Query() используется для вывода записей, которые никак не связанны со страницей или для создания множественных циклов. Выглядят эти циклы аналогично циклам с использование функции query_posts(). Параметры для WP_Query() такие же.
Особенностью циклов на основе WP_Query() является создание нового объекта ($query), который не связан с аналогичным глобальным объектом $wp_query и поэтому никак не нарушается структура текущей страницы.
Так же, мы можем использовать новый объект в других целях, не только для вывода записей, но и для различного рода проверок.
Пример цикла WP_query()
<?php // The Query $query = new WP_Query( $args ); // The Loop if ( $query->have_posts() ) { while ( $query->have_posts() ) { $query->the_post(); echo '<li>' . get_the_title() . '</li>'; } } else { // Сообщения не найдены } /* Восстановления исходных данных сообщение */ wp_reset_postdata();
Пример множественных циклов WP_guery
<?php // The Query $the_query = new WP_Query( $args ); // The Loop while ( $the_query->have_posts() ) { $the_query->the_post(); echo '<li>' . get_the_title() . '</li>'; } /* Восстановления исходных данных сообщения * Примечание: Так как мы далее создаем новые WP_Query мы не топтать * Оригинальная wp_query $, и это не дмолжны быть сброшены. */ wp_reset_postdata(); /* Второй Query (without global var) */ $query2 = new WP_Query( $args2 ); // Второй Loop while( $query2->have_posts() ) { $query2->next_post(); echo '<li>' . get_the_title( $query2->post->ID ) . '</li>'; } // Восстановления исходных данных сообщение wp_reset_postdata(); //wp_reset_postdata() используется как раз для того, //чтобы вернуть правильные данные в переменную $post. ?>
Цикл WordPress на основе get_posts()
Функция get_posts() используется для создания еще одного цикла, помимо основного. get_posts() получает записи (посты, страницы, вложения) из Базы Данных по указанным критериям.
Цикл WordPress на основе get_posts() считается самым удобным вариантом вывода нужных записей в нужном порядке. get_posts() в большинстве случаев полностью заменяет функцию WP_query(). Например,
- если нужно вывести 7 последних постов в сайдбаре или
- несколько случайных записей в футере — нет проблем;
- нужно вывести все картинки, прикрепленные к посту или
- вывести записи с определенным произвольным полем — get_posts() справится и с этим.
Функция get_posts() аналогично с query_posts() работает на основе класса WP_query() и поэтому передаваемые параметры одинаковые.
Примечание: Класс WordPress (тоже, что и класс php), это самодостаточный код выполняющий определенную функцию. Класс имеет свое имя, содержит собственные константы, переменные (называемые свойствами) и функции (называемые методами).
Пример цикла get_posts()
Выведем 5 записей из рубрики 13
<?php global $post; // не обязательно $args = array('category' => 13); // 5 записей из рубрики 13 $posts = get_posts($args); foreach( $posts as $post ){ setup_postdata($post); // стандартный вывод записей } wp_reset_postdata(); // сбрасываем переменную $post ?>
На этом про Цикл WordPress все!
©www.wordpress-abc.ru
www.wordpress-abc.ru
If you’re just getting started with WordPress, you’ll notice that every blog post you write gets displayed on the front page of your website. Traditionally, this is how blogs have worked with a chronological display of the author’s posts. But sometimes you want the post to appear in a different page instead. Typically this happens when you want to maintain several «categories» of posts and you don’t want your visitors to get confused between the various sections. In this tutorial, I’ll take you through a step-by-step explanation of how to achieve this.
Deciding on the Front Page
If you don’t want all of your posts to appear on the front page, you have to ask yourself what your homepage should look like. Do you want it to display a static page that never changes? Or do you want it to contain everything except certain posts belonging to a specific category? The answer to this will determine what steps you need to take.
For example, say you want your front page to always show the same content –an «About Me» landing page for example. To achieve this, you need to follow my earlier tutorial on how to create a static landing page for WordPress.
Once you’ve created your static landing page, visiting the home URL of your WordPress blog will show you content that never changes like this example page on my website:
When you create a post in WordPress, you can assign it to several «categories» that are defined by you. If you scroll down a bit in this tutorial, you see a screenshot of how to do this. If you want your front page to display everything except posts belonging to a certain category, install a plug-in like Ultimate Category Excluder which will get the job done for you.
www.webhostinghero.com
Настраиваем query_posts()
Типичный цикл по умолчанию выглядит вот так:
<?php // The WordPress Loop if (have_posts()) : while (have_posts()) : the_post(); ... endwhile; else: ... endif; ?>
Информация, отображаемая в цикле, зависит от огромного количества факторов, включая запрашиваемый урл и соответствующий шаблон, генерирующий страницу. Например, когда кто-то посещает главную страницу сайта, исходный цикл выводит записи из всех категорий в количестве, заданном в админке.
Но что, если мы хотим вместо отображения записей из всех категорий исключить содержимое определенной, чтобы вывести их в отдельном месте страницы. Это идеальная задача для query_posts(), которая легко с ней справится:
<?php query_posts('cat=-9'); // исключаем категорию с ID = 9 if (have_posts()) : while (have_posts()) : the_post(); ... endwhile; else: ... endif; ?>
Но нужно учитывать необходимость внести некоторые модификации в стандартный код вызова: убедиться, что запрос был сделан правильно и сбросить запрос в состояние по умолчанию сразу после выполнения.
<?php global $query_string; $posts = query_posts($query_string.'&cat=-9'); if (have_posts()) : while (have_posts()) : the_post(); ... endwhile; else: ... endif; wp_reset_query(); ?>
Тег wp_reset_query восстанавливает оригинальный запрос query_posts и используется при применении в шаблонах нескольких последовательных циклов.
Используя такой шаблон можно легко вносить нужные правки в запрос, например, сделав такой
$posts = query_posts($query_string.'&cat=-7,-8,-9&posts_per_page=3&order=ASC');
что значит вывести 3 записи, исключив 7,8,9 категории и отсортировать записи по алфавиту.
Ключ к успешному использованию query_posts заключается в сохранении оригинального формата запроса с помощью $query_string переменных. Будучи однажды подключенными, можно добавить столько параметров, сколько нужно (подробнее тут https://codex.wordpress.org/Function_Reference/WP_Query#Parameters ).
Этот способ хорош, но не лишен недостатков. query_posts использует дополнительные запросы к базе данных и может повлиять на работоспособность других условных тегов, таких как is_page() и is_ single(). Поэтому рекомендуется не использовать этот способ, хотя он и работоспособен, а заменить его на WP_Query с которым точно проблем не будет.
Настраиваем WP_Query
Для полного контроля над любым количеством циклов, WP_Query – самый лучший способ. Если нужно модифицировать дефолтовый цикл, то это выглядит очень похоже на query_posts:
<?php // The WordPress Loop - customized with WP_Query $custom_query = new WP_Query('cat=-9'); while($custom_query->have_posts()) : $custom_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query ?>
Применяются те же параметры, что и для query_posts, поэтому для модификации числа постов, используемыхисключаемых рубрик, порядка сортировки делается все то же самое.
$custom_query = new WP_Query('cat=-7,-8,-9'); // исключить категории $custom_query = new WP_Query('posts_per_page=3'); // ограничить количество $custom_query = new WP_Query('order=ASC'); // порядок сортировки
А также любые нужные комбинации
$custom_query = new WP_Query('cat=-7,-8,-9&posts_per_page=3&order=ASC');
В дополнение к сферам применения, мы также можем создавать и настраивать дополнительные множественные циклы, вот типовой пример:
<?php // Loop 1 $first_query = new WP_Query('cat=-1'); // исключили категорию 1 while($first_query->have_posts()) : $first_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query // Loop 2 $second_query = new WP_Query('cat=-2'); // исключили категорию 2 while($second_query->have_posts()) : $second_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query // Loop 3 $third_query = new WP_Query('cat=-3'); // исключили категорию 3 while($third_query->have_posts()) : $third_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query ?>
Каждый из этих циклов может быть размещен в любом месте шаблона, не нужно вписывать их последовательно. Например, первый цикл может быть в сайдбаре, второй в футере и т.д.. И каждый выводит свои собственные списки записей, в соответствии с параметрами.
При желании можно комбинировать вместе 3 разных способа query_posts , get_posts и WP_Query в множественных циклах. А в версии вордпресса 3.3 появилась функция is_main_query, позволяющая модифицировать только главные объекты в WP_Query, подробнее на https://codex.wordpress .org/Functi on_Reference/i s_main_query
Настраиваем get_posts
Самый легкий и безопасный способ создать множественные циклы, это get_posts. Просто добавляете в нужном месте шаблона
<?php global $post; $args = array('category' => -9); // исключили категорию $custom_posts = get_posts($args); foreach($custom_posts as $post) : setup_postdata($post); ... endforeach; ?>
Этот код создает циклы всех постов за исключением указанной рубрики. Конечно, исключение рубрик не единственный способ применения циклов. Опять же, используя различные параметры можно получить любой нужный результат.
Но есть один момент, get_posts требует передачи параметров в виде массива, т.е.
$args = array('category'=>-7,-8,-9, 'numberposts'=>3, 'order'=>'ASC');
Также обратите внимание, что мы используем numberposts вместо posts_per_page для ограничения количества записей. В соответствии с кодексом WP параметр posts_per_page все же должен работать, но если нет — то замените его на numberposts.
Стандартный цикл, а также модифицированные с помощью query_posts и WP_Query поддерживают постраничную навигацию, используя next_posts_link и previous_posts_link, а вот get_posts не поддерживает ее, отображая статический список постов, соответствующих выбранному критерию и все.
Подытожим:
- Чтобы модифицировать стандартный цикл, используйте query_posts()
- Чтобы модифицировать иили создать множественные циклы, используйте WP_Query()
- Чтобы создать статический, дополнительный цикл, используйте get_posts()
Цикл не беспокоится о разметке
Это правда. Можно использовать все, что нам в голову придет. Вот пример типового цикла, закрытого в тег <div>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <p class="meta">Posted on <?php the_time('F jS, Y'); ?></p> <?php the_content('Read More'); ?> <p><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', '); ?></p> </div> <?php endwhile; ?> <div class="next-posts"><?php next_posts_link('« Older Entries') ?></div> <div class="prev-posts"><?php previous_posts_link('Newer Entries »') ?></div> <?php endif; ?>
И вот точно такой же цикл, оформленный в стиле нумерованного списка
<?php if (have_posts()) : ?> <ol> <?php while (have_posts()) : the_post(); ?> <li <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <p class="meta">Posted on <?php the_time('F jS, Y'); ?></p> <?php the_content('Read More'); ?> <p><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', '); ?></p> </li> <?php endwhile; ?> </ol> <?php endif; ?>
А вот пример списка определений
<?php if (have_posts()) : ?> <dl> <?php while (have_posts()) : the_post(); ?> <dt <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> </dt> <dd> <?php the_excerpt(); ?> </dd> <?php endwhile; ?> </dl> <?php endif; ?>
Обратите внимание, что не только разметка отличается в этих трех примерах, но и используемые функции разные. Например, в третьем случае использовался the_excerpt() для вывода цитат вместо контента.
По умолчанию the_excerpt() выводит первые 55 слов записи, если не задано поле цитата записи. Поэтому для постов длиной меньше 55 слов будет выведено полное содержание, более 55 слов – только часть.
Мораль такая — циклы WordPress очень удобная, гибкая и мощная штука — вы можете как угодно применять их и где угодно размещать.
Мощь WP_Query
Много магии осуществляется с помощью функции WP_Query, которая определенно стоит того, чтобы с ней разобраться. Как мы видели ранее, каждое выполнение цикла основано на запросе, соответствующем типу загруженной страницы, настройкам сайта и т.п.. Этот запрос по умолчанию может быть изменен и заменен с помощью WP_Query.
В большинстве случаев вы можете сохранить оригинальный запрос и модифицировать только некоторые параметры, например вот так
<?php $custom_query = new WP_Query('cat=10&showposts=2&paged='.$paged); while($custom_query->have_posts()) : $custom_query->the_post(); ... endwhile; next_posts_link('« Старые записи'); previous_posts_link('Новые записи »'); wp_reset_postdata(); // сбрасываем запрос ?>
Как и в предыдущих примерах, изменением параметров в новом WP_Query вы легко настраиваете вывод любого набора записей. Давайте подробно разберем наиболее типичные способы применения.
Отображение разного количества записей
Глобальная настройка количества отображаемых постов настраивается в админке, но мы можем менять это значение прямо в цикле. Например, так мы задаем свое значение вместо значения по умолчанию.
$custom_query = new WP_Query('showposts=6&paged='.$paged);
Таким образом мы ограничим количество выводимых постов шестью, вместо десяти (значение по умолчанию). Чтобы вывести абсолютно все записи, нужно указать параметр равный «-1».
Исключаем некоторые категории
Одна из самых популярных задач – исключение записей определенной категории на главной странице сайта. Например, у вас есть несколько записей про хомячков, но вы хотели бы убрать их с главной страницы сайта. Этот контент остается в базе данных, отображается в своей рубрике и RSS ленте, но только не на главной. Есть множество способов сделать это, но мы применим самое простое из решений…да, это WP_Query class:
$custom_query = new WP_Query('cat=-3&paged='.$paged); // нет хомячкам
В общих случаях, знак минус означает исключить данный параметр.
Поэтому мы исключили третью рубрику (про хомячков).
Другие возможности исключить содержимое этой рубрики — использовать php функцию continue и пропускать записи определенной категории, скрывать контент с помощью css и javascript, править файлы ядра вордпресс и использовать плагины. Согласитесь, WP_Query однозначно лучше.
Изменяем порядок сортировки
WordPress относится к приложениям LIFO типа — last in, first out, т.е. последний пришел, первый вышел. Что означает, что мы видим сначала свеже опубликованные записи, а старички спрятаны глубоко в недрах навигации. Это рационально, т.к. большинство блоговых сайтов стремится первым показать самый свежий контент. Это дает людям смысл периодически возвращаться на сайт, т.к. они смогут найти что-то новенькое прямо на первой странице сайта. Но это не идеальный вариант для каждого типа сайтов.
Допустим, вы используете вордпресс для того, чтобы публиковать свой роман. Это означает, что вы писали и публиковали его хронологически, главу за главой. Поэтому, когда посетители приходят на ваш сайт, вы хотите показать им сначала главу Один, но она является фактически самой старой записью, поэтому вместо этого они увидят самую последнюю опубликованную главу. Но нет проблем, всего навсего изменим порядок сортировки:
$custom_query = new WP_Query('orderby=date&order=ASC&paged='.$paged);
Покажем специфические страницы, встраивая страницу в страницу
Другой интересный и полезный цикл, это использовать новый WP_Query class для отображения только одной определенной страницы. Это может быть полезно из разных соображений, например, для встраивания одной страницы в другую. Вот пример запроса, когда содержимое страницы About встраивается в другую страницу:
$custom_query = new WP_Query('pagename=about&paged='.$paged);
Обратите внимание, что в pagename нужно использовать не реальное название страницы, а ее слаг.
Пример использования множественных циклов
Ничто не заставляет вас ограничиваться только одним циклом. Вы можете использовать ровно столько, сколько вам нужно. Фактически, это в целом нормально иметь множественные циклы в шаблоне. Простым примером будет главная страница, которая показывает полное содержание трех новых публикаций. А затем в сайдбаре, в втором цикле показывает выдержки из остальных семи публикаций. И все работает чудесным образом.
А вот пример более сложной реализации. Допустим, у нас есть милый четырех колоночный шаблон. В левом сайдбаре мы покажем выдержки из одной категории. Затем в главной центральной части, разбитой на две колонки, мы покажем 10 последних записей по 5 в каждой. И затем в правом сайдбаре, мы покажем еще 10 записей, идущих после первых десяти.
Таким образом у нас получается 4 цикла
1 — Левый сайдбар | 2 — Левая колонка | 3 — Правая колонка | 4 — Правый сайдбар |
---|---|---|---|
new WP_Query( 'cat=7&showposts=3'); 3 последние записи из рубрики номер 7 |
new WP_Query( 'cat=-7&showposts=5'); 5 последних записей, кроме из рубрики номер 7 |
new WP_Query( 'cat=-7&showposts=5 &offset=5'); еще 5 последних записей, кроме из рубрики номер 7 |
new WP_Query( 'cat=-7&showposts=10 &offset=10'); еще 10 последних записей, кроме из рубрики номер 7 |
которые будут находиться в index.php, но также разместить их можно будет где угодно еще.
Теперь необходимо разобраться с используемыми параметрами, которые помогают отображать именно то, что нам нужно.
Параметр cat
- Цикл 1 — отображает записи только из 7 рубрики (cat=7)
- Цикл 2 — отображает записи кроме 7 рубрики (cat=-7)
- Цикл 3 — отображает записи кроме 7 рубрики (cat=-7)
- Цикл 4 — отображает записи кроме 7 рубрики (cat=-7)
Параметр showposts
- Цикл 1 — отображает только 3 записи (showposts=3)
- Цикл 2 — отображает только 5 записей (showposts=5)
- Цикл 3 — отображает только 5 записей (showposts=5)
- Цикл 4 — отображает только 10 записей (showposts=10)
Параметр offset
- Цикл 1 — не используется Цикл 2 — не используется
- Цикл 3 — пропускает первые 5 записей (offset=5)
- Цикл 4 — пропускает первые 10 записей (offset=10)
Таким образом, каждый цикл модифицирован для отображения желаемых записей. Последнее, что останется рассмотреть, это нужна ли нам навигация в одном из этих циклов. В обычных циклах по умолчанию мы используем теги posts_nav_link() для вывода навигационных ссылок на главную, рубрики и архивы.
Для этого примера мы создадим навигацию на предыдущие и следующие записи в втором цикле. А также настроим отображение полных записей или цитат записей в нужных местах.
Цикл 1 — Левый сайдбар
$first_query = new WP_Query('cat=7&showposts=3'); while($first_query->have_posts()) : $first_query->the_post(); the_excerpt(); endwhile; wp_reset_postdata();
Отображает 3 кратких записи.
Цикл 2 — Левая колонка
$second_query = new WP_Query('cat=-7&showposts=5&paged='.$paged); while($second_query->have_posts()) : $second_query->the_post(); the_content(); endwhile; next_posts_link(); previous_posts_link(); wp_reset_postdata();
Отображает 5 полных записей, а после них выводит ссылки на следующие и предыдущие записи.
Цикл 3 — Правая колонка
$third_query = new WP_Query('cat=-7&showposts=5&offset=5'); while($third_query->have_posts()) : $third_query->the_post(); the_content(); endwhile; wp_reset_postdata();
Цикл 4 — правый сайдбар
$fourth_query = new WP_Query('cat=-7&showposts=10&offset=10'); while($fourth_query->have_posts()) : $fourth_query->the_post(); the_content(); endwhile; wp_reset_postdata();
Отображает 10 полных записей.
Понятно, что стоит добавить нужные html коды верстки и разметки для создания стиля и структурирования отображения контента, но уже этого кода почти достаточно для создания своего собственного шаблона.
iwsm.ru
Основные и вторичные запросы
Основной запрос (или основной цикл) в WordPress это тот, который выполняется на раннем этапе загрузки ядра, он строится из запрошенного URL, настроек постоянных ссылок и т.д. Во время основного запроса WordPress определяет такие параметры как количество записей на страницу, используемый шаблон в теме и прочие. Основной запрос делает сам WordPress.
Вторичный запрос это тот, который выполняется дополнительно к основному. Например:
- Вывести в боковой колонке список самых популярных записей
- Вывести выделенные записи в слайдере на главной странице
- Вывести записи из той же категории в блоке «похожие записи»
Вторичные запросы выполняются с помощью класса WP_Query
, или с помощью одной из вспомогательных функций get_posts()
, query_posts()
и т.д. Если вы не знакомы с WP_Query
, советуем прочитать нашу статью.
Основным отличием query_posts()
от других вспомогательных функций является то, что query_posts()
заменяет основной цикл на новый, вторичный цикл WordPress. Это значит, что в цикле с query_posts()
мы можем работать так же, как и в обычном основном цикле.
Для сравнения рассмотрим цикл для вывода популярных записей с помощью WP_Query
:
// Вторичный цикл $popular = new WP_Query( ... ); while ( $popular->have_posts() ) { $popular->the_post(); the_title(); // вывести название the_content(); // вывести содержимое }
Этот же цикл с помощью query_posts()
:
// Вторичный цикл query_posts( ... ); while ( have_posts() ) { the_post(); the_title(); // вывести название the_content(); // вывести содержимое }
Безусловно второй вариант выглядит немного чище и привычнее, поскольку такая конструкция чаще всего встречается при работе с основным циклом WordPress.
Именно поэтому разработчики часто думают, что query_posts()
изменяет основной запрос WordPress, но это не так. Функция query_posts()
заменяет основной цикл новым вторичным циклом, и происходит это после выполнения основного запроса.
$wp_query и $wp_the_query
После выполнения основного запроса WordPress помещает его результат в глобальную переменную $wp_the_query
, а в глобальной переменной $wp_query
хранится всего лишь ссылка на $wp_the_query
. Функции have_posts()
, the_post()
и прочие работают именно с глобальным объектом $wp_query
.
Чтобы в этом убедиться достаточно взглянуть на реализацию подобных функций:
function have_posts() { global $wp_query; return $wp_query->have_posts(); }
Функция query_posts()
создает новый вторичный запрос с помощью WP_Query
и помещает результат в эту же глобальную переменную $wp_query
:
function query_posts( $query ) { $GLOBALS['wp_query'] = new WP_Query(); return $GLOBALS['wp_query']->query( $query ); }
Таким образом функции, которые предназначены для работы с основным циклом WordPress начинают работать с нашим вторичным запросом, а основной запрос остался в глобальной переменной $wp_the_query
, ссылку на которую можно восстановить с помощью функции wp_reset_query()
.
function wp_reset_query() { $GLOBALS['wp_query'] = $GLOBALS['wp_the_query']; wp_reset_postdata(); }
После этого, функции have_posts()
и другие вновь работают с основным циклом WordPress, но разработчики часто об этом забывают, в результате чего перестает работать пагинация, некоторые виджеты и прочее.
Пагинация
Самым частым результатом использования query_posts()
является сломанная пагинация, когда например первые две страницы работают, а третья и четвертая возвращают ошибку 404. Давайте рассмотрим как, и почему это происходит.
По умолчанию WordPress показывает десять записей на одной странице. Допустим у нас всего двадцать записей, это всего две страницы. Изменить количество записей на страницу можно легко с помощью query_posts()
в начале нашего шаблона index.php или archive.php:
global $query_string; query_posts( $query_string . '&posts_per_page=5' );
Таким образом на каждой странице у нас будет пять записей, а не десять, а наш плагин для пагинации будет отображать четыре страницы вместо двух. Все сходится, но при переходе на третью страницу мы получаем ошибку 404. Почему это происходит?
Напоминаем, что основной запрос WordPress происходит еще до того, как обрабатываются шаблоны index.php или archive.php, где происходит наша «подмена». В основном запросе количество записей на страницу — десять, и всего две страницы. Третей и четвертой страниц в основном запросе нет.
Именно основной запрос определяет какой шаблон темы будет использоваться, и при запросе третей или четвертой страницы WordPress будет использовать шаблон 404.php.
Изменение количества записей на страницу это самый простой и явный пример ошибок с query_posts()
. Гораздо сложнее подобные ошибки отловить, если вы например исключаете метку или категорию из списка записей на главной, или добавляете произвольный тип записей в поток.
Событие pre_get_posts
Наиболее правильным способом изменить основной цикл WordPress является событие pre_get_posts
, которое происходит перед каждым запросом WP_Query
. Работать с этим событием можно в плагине или в файле functions.php вашей темы:
function my_pre_get_posts( $query ) { if ( ! is_admin() && $query->is_main_query() ) { $query->set( 'posts_per_page', 5 ); } } add_action( 'pre_get_posts', 'my_pre_get_posts' );
Важно отметить, что pre_get_posts
вызывается для каждого запроса WP_Query
, включая основной запрос, навигационное меню, вторичные запросы в виджетах и прочее. С помощью метода is_main_query()
мы изменяем параметры только основного запроса, а с помощью проверки is_admin()
мы меняем запрос только на лицевой части сайта и не в административной панели.
Результат такого подхода тот же, что и с query_posts()
, но в этот раз будет работать пагинация, а загрузка страницы будет происходить быстрее, поскольку с pre_get_posts
мы действительно изменили основной запрос перед его выполнением и не выполняли вторичных запросов.
Альтернативы query_posts()
Если вам необходимо выполнить вторичный запрос в WordPress, воспользуйтесь функцией get_posts()
или конструкцией new WP_Query()
. При работе с ними ваш код будет более явным и понятным для читающих.
Когда вам необходимо изменить основной запрос WordPress перед его выполнением, самым простым способом является событие pre_get_posts
, или фильтр request
, который выполняется еще раньше, чем pre_get_posts
и только для основного запроса.
Если у вас возникли вопросы про query_posts()
или WP_Query
, оставьте комментарий и мы обязательно вам ответим.
wpmag.ru
Цикл 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(), которая выполняет новый запрос, создает новый массив записей и отматывает назад счетчик цикла.
Если нужно сохранить (не перезаписывать) результаты исходного запроса, можно создать копию $wp_query или создать новый объект запроса.
Использование функции query_posts()
// 10 последних записей из категории cat1 <?php query_posts('category_name=cat1&posts_per_page=10'); ?> <?php while (have_posts()) : the_post(); ?> ... <?php endwhile;?>
Внимание! Чтобы не нарушалась «пагинация» — работа ссылок «Предыдущие записи» — для функции query_posts() необходимо использовать параметр paged:
$page_num = $paged; if ($pagenum='') $pagenum =1; query_posts('showposts=4&paged='.$page_num=3');
Рекомендации автора плагина PageNavi (wp_pagenavi ):
Плагин wp_pagenavi создает страничную навигацию (страница 1, страница 2 и т.д.) для страниц записей, но навигация не будет работать, если в теме используется вызов функции query_posts() вида
query_posts('cat=8'); или query_posts( array( 'cat' => 8 ) );
Должно быть так:
query_posts( array( 'cat' => 8, 'paged' => get_query_var('paged') ) );
если это не сработает, попробуйте передать переменную page:
query_posts( array( 'cat' => 8, 'paged' => get_query_var('page') ) );
(http://scribu.net/wordpress/wp-pagenavi/right-way-to-use-query_posts.html)
Внимание! Использование функции query_posts() означает изменение глобального массива и не рекомендуется. Предпочтительнее создание нового объекта WP_Query или применение фильтра pre_get_posts .
Создание нового объекта WP_Query
Если нужно сохранить (не перезаписывать) результаты исходного запроса, можно создать копию $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();
Изменение количества записей только на главной странице — query_posts
Новый запрос с помощью функции query_posts():
<?php if (is_front_page()) { $page_num = $paged; if ($pagenum='') $pagenum =1; query_posts('showposts=4&paged='.$page_num); } ?> <?php //while ( have_posts() ) : the_post(); ?>
На главной будут выводиться 4 записи, а на страницах рубрик, меток и т.д. — в соответствии с настройкой, заданной в
Параметры — Чтение — На страницах блога отображать не более 10 записей
Изменение запросов с помощью фильтра pre_get_posts
Фильтр pre_get_posts применяется после формирования запроса но до его выполнения, т.е. его использование не создает дополнительной нагрузки!
Исключение рубрик на главной странице
Если нужно не показывать на главной / домашней странице записи блога из некоторых рубрик (например, с id= ‘1’ и ’67’), используйте в плагине или добавьте в файл functions.php код:
function exclude_category( $query ) { if ( $query->is_home() && $query->is_main_query() ) { $query->set( 'cat', '-1,-67' ); } } add_action( 'pre_get_posts', 'exclude_category' );
Изменение количества записей для разных случаев
В WordPress есть одна глобальная настройка для количества записей на главной странице блога и на страницах рубрик, архивов по месяцам и т.д. (Параметры — Чтение). Применяя фильтр, можно избирательно изменять эту и другие настройки, например, для главной страницы или страницы определенной рубрики.
Пример изменения параметра ‘posts_per_page’ (записей на странице):
function change_posts_per_page( $query ) { // изменять не в админке и только главный запрос if ( is_admin() || ! $query->is_main_query() ) return; if ( is_home() ) { // На главной показывать только 1 запись $query->set( 'posts_per_page', 1 ); return; } if ( is_post_type_archive( 'movie' ) ) { // 50 записей в архиве произвольноготипа'movie' $query->set( 'posts_per_page', 50 ); return; } } add_action( 'pre_get_posts', 'change_posts_per_page', 1 );
mblogm.ru
Использование Цикла
Цикл должен быть расположен в файле index.php и в любых других шаблонах, используемых для отображения записей.
Убедитесь, что включили вызов заголовка Шаблона (header.php), в верхней части Шаблонов вашей Темы. Если вы используете Цикл внутри собственного дизайна (и ваш дизайн не является шаблоном), установите WP_USE_THEMES в значение false.
<?php define('WP_USE_THEMES', false); get_header(); ?>
Цикл стартует здесь:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
и заканчивается здесь:
<?php endwhile; else: ?> <p><?php _e('Sorry, no posts matched your criteria.'); ?></p> <?php endif; ?>
Примеры Циклов
Стилизация Записей из различных Рубрик
Этот пример отображает каждую запись с заголовком (который используется в качестве Постоянной ссылки к записи), Рубриками и Содержимым. Это очень простой пример; вероятно ваши Шаблоны будут отображать больше информации, в таком случае стилизацию будет проще сделать с помощью CSS.
Для того чтобы извлечь больше пользы из этого примера, выделим записи из Рубрики с ID равным ‘3’. Для этого используется Тэг Шаблона in_category().
Тэги <!-- --> являются HTML-тэгами комментариев; если вы используете данный пример, эти тэги не будут отображаться в браузере. Они нужны только для комментирования кода.
<!-- Start the Loop. --> <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <!-- Далее проверяется, находится ли текущая запись в рубрике 3. --> <!-- Если да, то блоку div, будет присвоен класс "post-cat-three". --> <!-- Иначе, блоку div будет присвоен класс "post". --> <?php if ( in_category('3') ) { ?> <div class="post-cat-three"> <?php } else { ?> <div class="post"> <?php } ?> <!-- Отобразить Заголовок как постоянную ссылку на Запись. --> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <!-- Отобразить время. --> <small><?php the_time('F jS, Y'); ?></small> <!-- Отобразить Содержимое Записи внутри div. --> <div class="entry"> <?php the_content(); ?> </div> <!-- Отобразить список Рубрик Записи, разделенных запятой. --> <p class="postmetadata">Posted in <?php the_category(', '); ?></p> </div> <!-- closes the first div box --> <!-- Остановить Цикл (но есть ключевое слово "else:" - смотрите далее). --> <?php endwhile; else: ?> <!-- В первом "if" проверяется существуют ли каки-либо записи для --> <!-- вывода. Эта часть "else", говорит что делать, если записей не нашлось.--> <p>Sorry, no posts matched your criteria.</p> <!-- ДЕЙСТВИТЕЛЬНО остановить Цикл --> <?php endif; ?>
Запомните: Каждый раз, когда вы хотите использовать HTML код, вы должны находиться вне <?php ?> тэгов. PHP код (даже такие вещи как простые фигурные скобки: } ) должны быть внутри <?php ?> тэгов. Вы можете запускать и останавливать PHP код с тем чтобы вставлять в промежутки HTML код, с каждым if и else выражением, как показано в примере выше.
Исключение Записей из некоторых Рубрик
Этот пример может быть использован для исключения определенной Рубрики из обычного отображения. Он основан на предыдущем примере.
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <!-- Если запись находится в рубрике, которую мы хотим исключить, мы просто переходим к следующей записи. --> <?php if (in_category('3')) continue; ?> <div class="post"> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <small><?php the_time('F jS, Y'); ?></small> <div class="entry"> <?php the_content(); ?> </div> <p class="postmetadata">Posted in <?php the_category(', '); ?></p> </div> <!-- closes the first div box --> <?php endwhile; else: ?> <p>Sorry, no posts matched your criteria.</p> <?php endif; ?>
Запомните: Если вы используете этот пример для основной страницы, вы должны использовать другой Шаблон для архивов Рубрик. Иначе, WordPress будет исключать все записи в Рубрике 3, каждый раз, когда вы просматриваете Архив этой Рубрики!
Однако, если вы хотите использовать этот же файл шаблона, вы должны обойти это используя тэг is_home():
... <?php if (in_category('3') && is_home() ) continue; ?> ...
Благодаря этому записи из Рубрики 3 будут исключены только с главной страницы. Существуют другие Условные Тэги, которые можно использовать для управления выводом в зависимости от того выполняется ли определенное условие на запрашиваемой странице.
Пожалуйста запомните, что несмотря на то что запись не отображается, WordPress все равно ее считает, как если бы она отображалась — это значит, что если вы указали WordPress выводить максимум семь записей, и две, последние из семи находятся в Рубрике 3, на главной странице отобразяться только пять записей. Если вы столкнулись с такой проблемой, можно воспользоваться более сложным приемом, описанным в разделе «Дизайн и Раскладка. Часто задаваемые вопросы» или вы можете использовать query_posts, если вам нужно просто исключить одну рубрику из Цикла.
Множественные Циклы
Этот раздел посвящен расширенному использованию Цикла. Здесь будет немного технической информации — но пусть это вас не пугает. Мы начнем с самого простого и приложив немного сообразительности, терпения и энтузиазма, вы тоже сможете строить множественные Циклы.
Во-первых, «зачем нужно использовать множественные Циклы?» Множественные циклы могут понадобиться в том случае, если вам необходимо произвести какие-то различные дейстия над несколькими группами записей, и при этом расположить их на одной странице. Различные действия — могут означать все что угодно, вы ограничены только PHP-мастерством и собственной фантазией.
Мы перейдем к примерам ниже, но сначала вы должны ознакомиться с основами. Взгляните на простой Цикл. Он состоит из:
<?php if (have_posts()) : ?> <?php while (have_posts()) : the_post(); ?> <!-- атрибуты записи ... --> <?php endwhile; ?>
Проще говоря (люди, знакомые с PHP и языком кода, могут пропустить), вышеуказанное можно прочитать как: Если мы собираемся отображать записи, тогда получим их по одной. Для каждой записи в списке отобразить соответствующие ей <!-- атрибуты записи ... -->. Когда дойдем до последней записи, остановиться. Строка (ки) <!-- атрибуты записи ... --> зависит от шаблона.
Слова атрибуты записи: в этом примере простой заменитель части кода, который описывает как форматировать и отображать каждую запись на странице. Этот код может быть изменен в зависимости от того, каким вы хотите видеть свой WordPress. Если откроете файла index.php темы Кубрика, секция атрибуты записи будет выглядеть вот так:
<?php while (have_posts()) : the_post(); ?>
Выше:
<?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?>
Разъяснение для кодеров там же: have_posts() и the_post() являются удобными обертками вокруг глобального объекта $wp_query, в котором происходят все эти действия. $wp_query вызывается в заголовке блога и аргументы запроса передаются к нему через GET и PATH_INFO. Приняв аргументы, $wp_query, строит и выполняет запрос к базе данных, а результаты запроса возвращает в виде массива записей. Этот массив записывается в объект и также возвращается назад в заголовок блога, где он заполняется в глобальный массив $posts (для обратной совместимости со старыми версиями циклов).
После того как WordPress загрузил заголовок блога и передал его в шаблон, мы перейдем к нашему Циклу записей. have_posts() просто вызывает $wp_query->have_posts(), который проверяет счетчик цикла на наличие каких-либо записей в массиве записей. Также the_post() вызывает $wp_query->the_post(), который увеличивает счетчик цикла и устанавливает глобальную переменную $post, также как и все данные записей. Один раз выполнив Цикл,have_posts() вернет false и мы закончим.
Примеры Циклов
Далее следуют два примера использования множественных циклов. Ключем к использованию множественных циклов является тот факт, что $wp_query может быть вызван только один раз. Для того чтобы обойти это, можно повторно использовать запрос, вызвав rewind_posts() или создав новый объект запроса. Это описывается в примере 1. В примере 2 описывается, использование переменной для хранения результатов запроса. В примере 3 документирована функция update_post_caches();, используемая для обхождения общих проблем с плагинами. Наконец, «множественные циклы в действии» включает множество идей, одна из которых — использование множественных циклов для взаимодействия записей из конкретной категории на домашней странице вашего блога.
Множественные Циклы. Пример 1
Для того чтобы второй раз использовать цикл, с таким же запросом, вызовите функцию rewind_posts(). Она сбросит счетчик цикла и позволит вам выполнить другой цикл.
<?php rewind_posts(); ?> <?php while (have_posts()) : the_post(); ?> <!-- получить записи... --> <?php endwhile; ?>
Если вы хотите использовать два различных запроса для получения записей, вы можете повторно запустить объект $wp_query, с помощью вызова query_posts(). query_posts() выполнит новый запрос, посторит новый массив записей, и сбросит счетчик цикла.
// Получить последние 10 записей в рубрике special_cat <?php query_posts('category_name=special_cat&posts_per_page=10'); ?> <?php while (have_posts()) : the_post(); ?> <!-- получить записи из рубрики special_cat... --> <?php endwhile;?>
Если вам нужно сохранить оригинальный запрос, вы можете создать новый объект запроса.
<?php $my_query = new WP_Query('category_name=special_cat&posts_per_page=10'); ?> <?php while ($my_query->have_posts()) : $my_query->the_post(); ?> <!-- получить записи из рубрики special_cat... --> <?php endwhile; ?>
Объект запроса my_query используется потому, что вы не можете использовать глобальные have_posts() и the_post(), поскольку они оба используются $wp_query. Вместо этого, используйте ваш новый объект $my_query.
Множественные Циклы Пример 2
Существует другой способ использования множественных Циклов, позволяющий обойти невозможность использования have_posts() и the_post(). Для этого, вам потребуется сохранить оригинальный запрос в переменную, а затем переназначить ее, за пределами другого Цикла. Этот способ позволяет использовать все стандартные функции, основывающиеся на глобальных данных.
Например:
// оригинальный запрос сохраняется в переменную $temp_query <?php $temp_query = $wp_query; ?> <!-- Получить записи... --> <?php query_posts('category_name=special_cat&showposts=10'); ?> <?php while (have_posts()) : the_post(); ?> <!-- Получить записи из рубрики special_cat... --> <?php endwhile; ?> // $wp_query вновь присвается значение оригинального запроса <?php $wp_query = $temp_query; ?>
Важно:В PHP5, оператор «=» создает ссылку на объект, вместо того что копировать его, как это было в php4. Чтобы Пример 2 заработал в PHP 5, вам нужно использовать следующий код:
// оригинальный запрос сохраняется в переменную $temp_query <?php $temp_query = clone $wp_query; ?> <!-- Получить записи... --> <?php query_posts('category_name=special_cat&showposts=10'); ?> <?php while (have_posts()) : the_post(); ?> <!-- Получить записи из рубрики special_cat... --> <?php endwhile; ?> // $wp_query вновь присвается значение оригинального запроса <?php $wp_query = clone $temp_query; ?>
Однако, этот второй пример не работает в WordPress 2.1.
Множественные Циклы Пример 3 — Плагины
Было установлено, что некоторые плагины плохо взаимодействуют с множественными циклами. В этих случаях было обнаружено, что плагины, имеющие отношение к ключевым словам и тэгированию записей, работают только с первым циклом на странице, который включает в себя подмножество всех записей. Если вы столкнулись с подобным, можно попробовать следующую реализацию основного цикла, с добавлением функции update_post_caches($posts). Эта функция сбрасывает кэш записей, и пока не документирована. Эта реализация будет использоваться во втором цикле на странице, только если первый цикл вернул подмножество записей.
Просто замените следующие строки:
<?php if (have_posts()) : ?> <?php while (have_posts()) : the_post(); ?> <!-- Получить записи... --> <?php endwhile; ?>
на эти:
<?php if (have_posts()) : ?> <?php while (have_posts()) : the_post(); update_post_caches($posts); ?> <!-- Получить записи... --> <?php endwhile; ?>
Множественные Циклы в Действии
Самый лучший способ понять как использовать множественные циклы — рассмотреть пример их использования. Чаще всего, множественные циклы используются для отображения двух (и более) списков записей на странице.Этот метод используется веб-мастером в том случае, когда он хочет отобразить не только последние записи, а еще и записи из некоторой рубрики.
Оставим в стороне все вопросы форматирования и CSS, представим что нам нужно отобразить два списка записей. Один из которых будет списком последних записей (стандартное количество записей равное 10,недавно добавили), и другой, который будет содержать только записи из рубрики «featured». Записи в рубрике «featured» должны быть отображены первыми, следущими за вторым списком записей (стандарт).Хитрость в том, что не одна запись не должна присутствовать в обоих рубриках.
Шаг 1. Получить записи только из рубрики «featured».
<?php $my_query = new WP_Query('category_name=featured&showposts=1'); while ($my_query->have_posts()) : $my_query->the_post(); $do_not_duplicate = $post->ID; ?> <!-- Получить записи... --> <?php endwhile; ?>
Говоря обычным языком, вышеуказанный код можно прочтитать так:
Установить $my_query равным результату запроса всех записей, где название рубрики featured, и кроме того, вернуть мне только одну запись. Также, установить значение переменной $do_not_duplicate равной ID-значению одиночной, возвращаемой записи. Выбрать то что описано в строке Получить записи вместе с параметрами форматирования, связанные с возвращаемой записью.
Обратите внимение, что нам понадобится использовать значение переменной $do_not_duplicate в следующем шаге, чтобы убедиться,что та же самая запись не попадет в оба списка.
Шаг 2. Второй цикл, получение Х последних записей (исключая первую).
Представленный код получает X последних записей (как описано в настройках WordPress), сохраняет одну, уже отображенную в первом цикле, и отображает остальные записи, в соответствии с секцией Получить записи.
<?php if (have_posts()) : while (have_posts()) : the_post(); if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts); ?> <!-- Получить записи... --> <?php endwhile; endif; ?>
Говоря обычным языком, вышеуказанный код можно прочтитать так:
Получить все записи; где запись равна $do_not_duplicate, то ничего не делать (continue), в другом случае отобразить все другие записи в соответствии с секцией Do stuff. Также, обновить кэш, чтобы плагины связанные с тэгированием и ключевыми словами работали нормально. Вернуть переменную $do_not_duplicate, содержащую ID записи, ранее выведенной.
Конечный результат
Here is what the final piece of code looks like without any formatting:
<?php $my_query = new WP_Query('category_name=featured&showposts=1'); while ($my_query->have_posts()) : $my_query->the_post(); $do_not_duplicate = $post->ID;?> <!-- Do stuff... --> <?php endwhile; ?> <!-- Do other stuff... --> <?php if (have_posts()) : while (have_posts()) : the_post(); if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts); ?> <!-- Do stuff... --> <?php endwhile; endif; ?>
В итоге мы получим два вывода. Первый вывод содержит самую свежую запись из категории ‘featured’. Второй вывод будет содержать X свежих записей (Как задано в настройках WordPress) за исключение записи которая уже показана в первом выводе. So, once the feature post is replaced with a new one, the previous feature will show up in standard post list section below (depending on how many posts you choose to display and on the post frequency). This technique (or similar) has been used by many in conjunction with knowledge of the Template Hierarchy to create a different look for home.php and index.php. See associated resources at the bottom of this page.
Note for Multiple Posts in the First Category
If showposts=2 or more, you will need to alter the code a bit. The variable $do_not_duplicate needs to be changed into an array as opposed to a single value. Otherwise, the first loop will finish and the variable $do_not_duplicate will equal only the id of the latest post. This will result in duplicated posts in the second loop. To fix the problem replace
<?php $my_query = new WP_Query('category_name=featured&showposts=1'); while ($my_query->have_posts()) : $my_query->the_post(); $do_not_duplicate = $post->ID;?>
with
<?php $my_query = new WP_Query('category_name=featured&showposts=2'); while ($my_query->have_posts()) : $my_query->the_post(); $do_not_duplicate[] = $post->ID ?>
Note that «showposts» can be any number. This changes $do_not_duplicate into an array. Then replace
<?php if (have_posts()) : while (have_posts()) : the_post(); if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts); ?>
with
<?php if (have_posts()) : while (have_posts()) : the_post(); if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?>
Where you continue the pattern for whatever showposts is set equal to (2 in this case).
Sources
This article on multiple loops is a combination of Ryan Boren and Alex King’s discussion about the Loop on the Hackers Mailing List as well as the tutorial written at MaxPower.
codex.wordpress.org