Настройка цикла loop в WordPress

Как упоминалось ранее, если и есть одна вещь, которую нужно понимать для того, чтобы быть реально крутым перцем-разработчиком шаблонов, так это как работает цикл и что вы можете с ним делать. Давайте посвятим наше внимание трем способам заставить WordPress Loop делать все, что нам угодно.

query_posts() https://codex.wordpress.org/Template_Tags/get_posts

Если вы работаете с одиночным циклом записей и просто хотите модифицировать тип записей, которые он возвращает, используйте query_posts(). Это идеально для ограничения количества записей, исключения записей из определенной рубрики и т.д..

WP_Query() https://codex.wordpress.org/Functi on_Reference/WP_Query Для мощной настройки множественных циклов, используйте WP_Query(). Настройкой дополнительных экземпляров WP_Query() в вашем шаблоне можно создать любое количество множественных циклов и настроить вывод каждого из них.

get_posts() https://codex.wordpress.org/Template_Tags/get_posts

Последний, но не худший, get_posts() – позволяет создать дополнительные циклы где угодно в шаблоне. get_posts() принимает те же параметры, что и query_posts() и идеален для вывода дополнительных циклов в сайдбаре, футере или где угодно.

Разберемся с ними подробнее.

Настраиваем 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('&laquo; Older Entries') ?></div>
<div class="prev-posts"><?php previous_posts_link('Newer Entries &raquo;') ?></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('&laquo; Старые записи');
previous_posts_link('Новые записи &raquo;');
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 коды верстки и разметки для создания стиля и структурирования отображения контента, но уже этого кода почти достаточно для создания своего собственного шаблона.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Scroll Up