Вывод статей в цикле wordpress

Статья для новичков и тех, кто уже немного знаком с WordPress, которая должна развенчать все мифы использования разных вариантов циклов в WordPress.
О Цикле WordPress и с чем его едят я уже писал и вскользь упоминал о разных вариантах циклов в описаниях функций. В этой статье я сделаю следующий шаг и расскажу о 3-х вариантах построения циклов для вывода записей и о плюсах и минусах каждого из них.
Правильное использование нескольких циклов на странице даст вам возможность выводить блоки с нужными записями, сортировать их в нужном порядке и при этом не переживать о нарушении логической структуры страницы и «ловле» различных багов.
Возможные варианты построения циклов вывода записей:
- Стандартный цикл и цикл на основе query_posts().
- Дополнительный цикл на основе WP_Query().
- Дополнительный цикл на основе get_posts().
Каждый из этих вариантов удобно использовать в разных ситуациях. Для использования каждого варианта не нужно изучать разный мануал, потому что все они работают с одинаковыми параметрами, нужно лишь понять как и где их использовать.
Для лучшего понимания и визуального восприятия работы функций запроса, изучите эту схему:
1) Стандартный Цикл и цикл на основе query_posts()
Я объединил 2 вида циклов (с query_posts() и начинающийся с if( have_posts() ), потому что технически они абсолютно одинаковые.
Давайте вспомним, как выглядит стандартный Цикл WordPress:
<?php
// проверяем есть ли посты в глобальном запросе – переменная $wp_query
if( have_posts() ){
// перебираем все имеющиеся посты и выводим их
while( have_posts() ){
the_post();
?>
<div <?php post_class(); ?> id=”post-<?php the_ID(); ?>”>
<h1><a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a></h1>
<?php the_content(); ?>
</div>
<?php
}
?>
<div class=”navigation”>
<div class=”next-posts”><?php next_posts_link(); ?></div>
<div class=”prev-posts”><?php previous_posts_link(); ?></div>
</div>
<?php
}
// постов нет
else {
echo “<h2>Записей нет.</h2>”;
}
Такой код мы можем встретить в файлах index.php, category.php и т.д. Эти файлы отвечают за вывод на странице списка записей. Этот цикл перебирает по очереди посты, которые выводятся на странице и во время перебора, используя Теги Шаблона (предназначенные для использования внутри Цикла), мы можем вывести различные данные поста (заголовок, текст, метаданные и т.д.).
Обратите внимание: в стандартном Цикле мы не указываем никаких данных для выборки записей, а сразу начинаем цикл с if( have_posts() ){ while( have_posts() ){… Это говорит о том, что данные уже существуют и их нужно просто обработать и вывести на экран.
«Уже существующие» данные находятся в глобальной переменной $wp_query и для каждого типа страниц WordPress определяются автоматически, т.е. WordPress заранее делает запрос в БД, на основе того какая страница сейчас отображается (категория, метка, статья, постоянная страница и т.д.) и результат запроса записывается в $wp_query, а затем мы используем эти данные для создания цикла. Интересно, что такой запрос делается функцией query_posts(), которую мы разберем ниже.
Обычный Цикл WordPress используется для базовых страниц WP (категории, метки, архивы по дате).
Цикл на основе query_posts()
query_posts() позволяет изменить базовый запрос и вывести нужный нам вариант записей.
Вариант 1
Мы можем изменить базовый запрос (сделать еще один запрос и перезаписать данные предыдущего запроса) и, например, вырезать ненужные категории из вывода или изменить количество выводимых записей, порядок сортировки и т.д.
<?php
global $query_string; // параметры базового запроса
// базовый запрос + свои параметры
query_posts( $query_string .’&cat=-6,-9&order=ASC&posts_per_page=20′ );
[СТАНДАРТНЫЙ ЦИКЛ WORDPRESS]
wp_reset_query(); // сброс запроса
?>
В этом примере мы создали новый запрос к БД, в котором использовали параметры базового запроса + свои параметры: исключили категории 6 и 9 (cat=-6,-9), а также отсортировали записи по порядку (order=ASC) и вывели 20 записей на странице вместо, установленных в настройках 10 (posts_per_page=20).
Полный список параметров, которыми можно сформировать нужный нам вывод, смотрите в описании функции query_posts().
Преимущества такого изменения в том, что если мы, например, изменим количество выводимых записей на странице с 10 (по умолчанию) на 20, то пагинация на странице автоматически подстроится под это изменение, потому что query_post() меняет данные глобальной переменной $wp_query, а пагинация строится именно на основе этих данных. Это лишь один из примеров, показывающий что query_posts() и поведение других функций на странице взаимосвязаны.
Но все же, изменять базовый запрос WP рекомендуется через фильтр pre_get_posts, а не через query_posts().
Вариант 2
Можно не использовать параметры базового запроса ($query_string), а полностью переписать базовый запрос:
query_posts( ‘cat=-6,-9&order=ASC’ );
Однако, такой подход по сути сотрет базовый запрос и создаст новый, который может быть составлен неправильно, поэтому полностью переписывать базовый запрос не рекомендуется. Лучше постараться решить задачу как-то по-другому.
Необходимость wp_reset_query()
Сбрасывать измененный запрос при использовании query_posts() нужно, потому что query_posts() переписывает глобальную переменную $wp_query которая отвечает за некоторые свойства страницы. Давайте посмотрим на примере.
Предположим нам на странице категории 6 (ID категории), нужно вывести данные только поста 9 (ID поста):
<?php
query_posts( ‘p=9’ );
if( have_posts() ){
while( have_posts() ){
the_post();
the_title();
the_content();
}
}
else {
echo ‘Записей нет’;
}
?>
В этом примере мы не сбросили запрос и функция query_posts() переписала глобальную переменную $wp_query. Теперь, кода мы проверим какая это страница (а это страница категории: is_category() == true), мы увидим, что это уже совсем не страница категории, а страница поста: is_single() == true. Т.е. следующий код вернет нам «Это страница поста», хотя на самом деле это страница категории:
if( is_category() ) echo ‘Это страница категории’; // не сработает
if( is_single() ) echo ‘Это страница поста’; // сработает
Ошибочка, которая может в последствии создать немало головной боли.
Когда использовать query_posts()?
Когда нужно немного изменить основной (базовый) запрос WordPress. В идеале: для исключения рубрики/метки (например, на главной странице); изменение направления сортировки; ограничения количества выводимых постов; исключения определенных постов из категории/метки и т.п. И напомню еще раз, для таких задач все же лучше использовать фильтр pre_get_posts.
Не нужно использовать query_posts() для создания нескольких циклов на одной странице, для вывода в сайдбар списка постов, для создания дополнительного вывода записей и т.п., для этих целей используйте циклы на основе get_posts(). К тому же, обе функции понимают параметры одинаково! Так зачем “платить” больше?..
2) Цикл на основе WP_Query()
Для вывода записей никак не связанных со страницей или создания множественных (дополнительных) циклов можно использовать циклы на основе класса WP_Query. Выглядят они аналогично циклам с использование query_posts(). Для WP_Query используются те же самые параметры, что и для query_posts().
Интересно, что WP_Query является ядром функций query_posts() и get_posts(), т.е. обе эти функции работают на основе этого класса.
Пример цикла: выведем все записи из категории 9:
<?php
// указываем категорию 9 и выключаем разбиение на страницы (пагинацию)
$query = new WP_Query( ‘cat=9&nopaging=1’ );
if( $query->have_posts() ){
while( $query->have_posts() ){
$query->the_post();
?>
<h2><a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a></h2>
<?php the_content(); ?>
<?php
}
wp_reset_postdata(); // сбрасываем переменную $post
}
else
echo ‘Записей нет.’;
?>
Пример создания множественных циклов на основе WP_Query():
<?php
// Цикл 1
$query1 = new WP_Query(‘cat=-1&nopaging=1’); // все посты, кроме категории 1
while( $query1->have_posts() ){
$query1->the_post();
// вывод записей
}
wp_reset_postdata();
// Цикл 2
$query2 = new WP_Query(‘cat=-2&nopaging=1’); // все посты, кроме категории 2
while( $query2->have_posts() ){
$query2->the_post();
// вывод записей
}
wp_reset_postdata();
// Цикл 3
$query3 = new WP_Query(‘cat=-3&nopaging=1’); // все посты, кроме категории 3
while( $query3->have_posts() ){
$query3->the_post();
// вывод записей
}
wp_reset_postdata();
?>
Особенность циклов на WP_Query() в том, что мы создаем новый объект $query, который никак не связан с аналогичным глобальным объектом $wp_query и поэтому мы никак не нарушаем структуру текущей страницы.
Также, мы можем использовать новый объект в других целях, не только для вывода записей, но и для различного рода проверок: например, записи какого типа страницы используются в этом новом объекте; можем узнать общее количество записей удовлетворяющих запросу ($query->found_posts) и т.д. Такие данные могут пригодится при создании дополнительных запросов с пагинацией или где-то еще (пример в комментариях).
Зачем нужно использовать wp_reset_postdata()?
В глобальной переменной $post хранятся данные текущего поста (если показывается страница поста, то данные этого поста). Когда срабатывает часть кода $query->the_post(), то в переменную $post записываются данные текущего поста в цикле и в конце цикла в этой переменной остаются данные последнего поста из этого цикла, а нужно чтобы $post всегда содержала данные текущего поста страницы. Т.е. получается до использования цикла $post->ID (ID текущего поста) было равно, допустим, 10, а после срабатывания цикла, та же самая переменная $post->ID уже равна, допустим, 56 (ID последнего поста из цикле), а нужно чтобы она по-прежнему равнялась 10.
wp_reset_postdata() используется как раз для того, чтобы вернуть правильные данные в переменную $post.
Когда использовать WP_Query()?
Если нужно вывести записи не затрагивая основной цикл (допустим записи в боковой панели), если нужно создать множественные запросы. Вообще, я не вижу никаких преимуществ циклов на WP_Query() над циклами с использованием get_posts() и поэтому рекомендую использовать get_posts() вместо WP_Query().
3) Цикл на основе get_posts()
Самый удобный вариант выводить нужные записи в нужном порядке — это выводить их с помощью get_posts() (см. описание). get_posts() в 99% случаев полностью заменяет WP_Query(): нужно вывести 10 последних постов в сайдбаре или 10 случайных записей в подвале — пожалуйста; нужно вывести все картинки прикрепленные к посту или вывести записи с определенным произвольным полем — get_posts() прекрасно справится с этой задачей.
get_posts() так же как и query_posts() работает на основе класса WP_Query() и поэтому передаваемые параметры одинаковые (см. их здесь).
#1. Пример цикла на основе get_posts(). Выведем 5 записей из рубрики 9:
<?php
global $post; // не обязательно
// 5 записей из рубрики 9
$myposts = get_posts( array(
‘category’ => 9
) );
foreach( $myposts as $post ){
setup_postdata( $post );
// стандартный вывод записей
}
wp_reset_postdata(); // сбрасываем переменную $post
?>
Код выведет именно 5 записей, хотя в аргументах мы указали только номер рубрики. Вызвано это тем, что у функции get_posts() есть параметры по умолчанию (см. описание), о которых нужно помнить. Например, если нам нужно вывести все записи из рубрики 9, то мы должны добавить еще параметр ‘nopaging’ => 1 или ‘posts_per_page’ => -1 (разницы нет).
Когда использовать get_posts()
Всегда, когда нужно просто вывести записи из БД в любом месте шаблона. Когда нужно создать несколько циклов. Так как get_posts() принимает те же параметры что и query_posts(), её очень удобно использовать для вывода записей по самым разным критериям.
Выводы
Где и какой из 3-х вариантов циклов использовать:
query_posts() — если нужно изменить/подправить стандартный вывод записей на страницах WordPress. Можно использовать 1 раз на странице;
get_posts() — если нужно вывести записи из Базы Данных. Можно использовать сколько угодно раз на странице;
- WP_Query() — во всех других случаях когда не подошли query_posts() и get_posts(). Класс WP_Query() является ядром query_posts() и get_posts() и может быть использован для каких-либо сложных случаев вывода.
Помните, что параметры для всех вариантов одинаковые и описаны они на этом блоге.
—
Попробуйте уже сейчас заказать комментарии к посту в Инстаграм с привлекательными скидками на сайте doctorsmm. Здесь Вам будут предложены разнообразные форматы текстов на выбор, а также возможность самостоятельно выбрать любое подходящее предложение.
Источник
Что такое цикл 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
Еще статьи
Похожие посты:
Источник
Основой структуры wordpress является запрос к базе данных и вывод данных в цикл. Какие бывают циклы, когда лучше применять тот или иной цикл, рассмотрим в данной статье.
Стандартный цикл wordpress (index.php, category.php, tag.php, архивы)
Обратите внимание: в стандартном Цикле мы не указываем никаких данных для выборки записей, а сразу начинаем цикл с if( have_posts() ){… Это говорит о том, что данные уже существуют и их нужно просто обработать и вывести на экран.
<?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()
Преимущества такого изменения в том, что если мы, например, изменим количество выводимых записей на странице с 10 (по умолчанию) на 20, то пагинация на странице автоматически подстроиться под это изменение, потому что query_post() меняет данные глобальной переменной $wp_query, а пагинация строиться именно на основе этих данных.
<?php global $query_string; // параметры базового запроса query_posts($query_string.’&cat=-6,-9&order=ASC&posts_per_page=20′); // базовый запрос + свои параметры ?>
[СТАНДАРТНЫЙ ЦИКЛ WORDPRESS]
<?php wp_reset_query();// сброс запроса?>
Не нужно использовать query_posts() для создания нескольких циклов на одной странице, для вывода в сайдбар списка постов, для создания дополнительного вывода записей и т.п., для этих целей используйте циклы на основе get_posts(). К тому же, обе функции понимают параметры одинаково! Так зачем «платить» больше?..
Пользовательские типы записей в шаблоне категорий (&post_type=video) — не очень хорошая идея, т.к. ломается пэйджинация. Типы записей лучше делать архивами.
Цикл на основе WP_Query()
Особенность циклов на WP_Query() в том, что мы создаем новый объект ( $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()
Самый удобный вариант выводить нужные записи в нужном порядке — это выводить их с помощью get_posts(). get_posts() в 99% случаев полностью заменяет WP_Query()
<?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 является легковесной служебной функцией для создания выборки постов.
Изменение основного цикла
Нужно добавлять перед if ( have_posts() ) :
<?php // Изменяем основной запрос
global $wp_query;
$params = array(
‘posts_per_page’ => -1
);
$params = array_merge( $wp_query->query, $params );
query_posts( $params ); ?>
Дальнейшая тема для изучения — глобальные переменные.
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.
Источник