3 способа создать цикл в WordPress: wp_query{}, get_posts(), query_posts()

# 3 СПОСОБА СОЗДАТЬ ЦИКЛ В WORDPRESS – WP_QUERY{}, GET_POSTS(), QUERY_POSTS()

![Изображение цикла в WordPress](https://example.com/path/to/image.png)

Эта статья предназначена для новичков и тех, кто уже немного знаком с WordPress. Она развеивает мифы о различных типах циклов в WordPress.

Ранее я писал о стандартном цикле WordPress и упоминал о разных вариантах цикла в описаниях функции wp_query. В этой статье я расскажу о трех вариантах циклов для вывода записей и о плюсах и минусах каждого из них.

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

## Возможные варианты циклов:

1. Стандартный цикл и цикл на основе query_posts()
2. Дополнительный цикл на основе WP_Query()
3. Дополнительный цикл на основе get_posts()

Каждый из этих вариантов удобен в разных ситуациях. Не нужно изучать разные руководства, чтобы использовать каждый вариант, так как они все работают с одними и теми же параметрами. Главное — понять, как и где их применять.

Для лучшего понимания и восприятия того, как работают функции запроса, изучите эту диаграмму:

![Как работают функции запроса в WordPress](https://example.com/path/to/diagram.png)

## 1) СТАНДАРТНЫЙ ЦИКЛ И ЦИКЛ НА ОСНОВЕ QUERY_POSTS()

Я объединил два типа циклов (с query_posts() и начинающаяся с if(have_posts())), потому что технически они абсолютно одинаковы.

Вспомним, как выглядит стандартный цикл WordPress:




        
id="post-">

Записей нет."; } ?> Этот код можно найти в файлах 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 Мы можем изменить базовый запрос (сделать другой запрос и перезаписать данные предыдущего запроса) и, например, убрать лишние категории из вывода или изменить количество выводимых записей, порядок сортировки и т.д. В этом примере мы создали новый запрос к базе данных, используя параметры базового запроса + наши параметры: исключили категории 6 и 9 (cat=-6, -9) и отсортировали записи (order=ASC), а также выводим 20 записей на странице вместо 10 (по умолчанию — posts_per_page=20). Смотрите функцию query_posts() для полного списка параметров, которые можно использовать для генерации нужного вывода. Преимущество такого изменения в том, что, если мы, например, изменим количество выводимых записей на странице с 10 (по умолчанию) на 20, тогда пагинация на странице автоматически настроится на это изменение, потому что query_posts() изменяет данные в глобальной переменной $wp_query, а пагинация строится на основе этих данных. Это всего лишь один пример, показывающий, что query_posts() и поведение других функций на странице взаимосвязаны. Рекомендуется изменять базовый запрос WordPress с помощью фильтра pre_get_posts, а не через query_posts(). #### ВАРИАНТ 2 Вы можете не использовать параметры базового запроса (query_string), а полностью переписать базовый запрос: query_posts( 'cat=-6,-9&order=ASC' ); Однако такой подход по сути сотрет базовый запрос и создаст новый, который может быть составлен некорректно, так что полное переписывание базового запроса не рекомендуется. Лучше попробовать решить задачу другим способом. ### ЗАЧЕМ НУЖЕН WP_RESET_QUERY()? Необходимо сбросить измененный запрос, когда вы используете query_posts(), потому что query_posts() переписывает глобальную переменную $wp_query, которая отвечает за некоторые свойства страницы. Рассмотрим пример. Предположим, нам нужно отобразить только запись с ID 9 на странице категории с ID 6: В этом примере мы не сбросили запрос, и функция 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() и get_posts(), поэтому обе эти функции основаны на этом классе. Пример цикла: давайте выведем все записи из категории 9: have_posts() ){ while( $query->have_posts() ){ $query->the_post(); ?>

Пример создания нескольких циклов на основе WP_Query(): 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 (например, 56 — это ID последней записи в цикле), но нам нужно, чтобы она снова равнялась 10. wp_reset_postdata() используется именно для того, чтобы вернуть правильные данные в глобальную переменную $post. ### КОГДА ИСПОЛЬЗОВАТЬ WP_QUERY()? Если вам нужно отображать записи без воздействия на основной цикл (например, записи в сайдбаре); если нужно создавать несколько запросов. В общем, я не вижу никаких преимуществ у циклов WP_Query() по сравнению с циклами на основе get_posts(), поэтому рекомендую использовать get_posts() вместо WP_Query(). ## 3) ЦИКЛИ НА ОСНОВЕ GET_POSTS() Наиболее удобный способ вывода нужных записей в нужном порядке — использовать get_posts(). get_posts() чаще всего лучше подходит для вашей задачи, например: - вам нужно отобразить 10 самых последних записей в сайдбаре. - нужно вывести 10 случайных записей внизу страницы. - нужно выв��сти все изображения, прикрепленные к записи. - нужно вывести записи с определенным мета-полем. get_posts() так же, как и query_posts(), работает на основе класса WP_Query, так что передаваемые параметры идентичны. ### ПРИМЕР ЦИКЛА НА ОСНОВЕ GET_POSTS() Давайте выведем 5 записей из категории 9: 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(), его очень удобно использовать для вывода записей согласно различным критериям. ## ЗАКЛЮЧЕНИЕ Где и какой из трех вариантов цикла использовать: - **get_posts()** — если хотите вывести записи из базы данных. Может быть использован столько раз, сколько нужно на странице. - **query_posts()** — если нужно изменить/исправить стандартный вывод записей на страницах WordPress. Может быть использован один раз на странице. - **WP_Query()** — во всех других случаях, когда query_posts() и get_posts() не подходят. Класс WP_Query() является основой query_posts() и get_posts(), и может использоваться для любых сложных случаев вывода. Помните, что параметры одинаковы для любого типа цикла и описаны в классе wp_query.

Leave a Reply

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