4 способи задати цикл Loop у WordPress
Цикл Loop у WordPress — це серце виведення контенту в темі. Саме через нього WordPress проходить по знайдених записах і підставляє в шаблон заголовок, посилання, уривок, контент, мініатюру, дату та інші дані.
Коротко: класичні чотири варіанти — це стандартний loop, query_posts(), WP_Query і get_posts(). У сучасній розробці також варто знати pre_get_posts для зміни головного запиту та rewind_posts() для повторного проходу по тих самих результатах.
Як loop працює всередині WordPress
Коли користувач відкриває сторінку сайту, WordPress формує головний запит у вигляді об’єкта WP_Query. У шаблоні працює знайома конструкція have_posts() + the_post(): перша перевіряє, чи є ще записи, а друга готує глобальні дані поточного запису.
У найпростішому вигляді стандартний loop має такий вигляд:
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID(); ?>">
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
</article>
<?php endwhile; ?>
<?php else : ?>
<p>Записів не знайдено.</p>
<?php endif; ?>
Це головний стандартний цикл. Він підходить для архівів, блогу, категорій, тегів, пошуку та інших місць, де WordPress уже сам сформував main query.
1. Стандартний цикл — найкращий старт
У index.php, home.php, archive.php, category.php, tag.php або search.php WordPress уже передає у шаблон готовий головний запит. Такий підхід не ламає пагінацію, не дублює логіку ядра і не створює зайвих SQL-запитів.
2. Цикл через query_posts() — історичний спосіб, але сьогодні небажаний
Функція query_posts() підміняє головний запит, тому легко отримати проблеми з пагінацією, умовними тегами та продуктивністю.
<?php
global $query_string;
query_posts( $query_string . '&posts_per_page=12&cat=-1,-2' );
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_title( '<h2>', '</h2>' );
endwhile;
endif;
wp_reset_query();
Практична порада: у новому коді замість query_posts() краще обирати pre_get_posts або окремий WP_Query.
3. Цикл через WP_Query — для кастомних і додаткових вибірок
WP_Query створює окремий запит і не ламає main query. Це хороший варіант для популярних записів, новин певної рубрики, схожих матеріалів та інших додаткових блоків.
<?php
$news_query = new WP_Query(
array(
'post_type' => 'post',
'posts_per_page' => 6,
'category_name' => 'news',
)
);
if ( $news_query->have_posts() ) :
while ( $news_query->have_posts() ) :
$news_query->the_post(); ?>
<article id="post-<?php the_ID(); ?>">
<h3><?php the_title(); ?></h3>
</article>
<?php endwhile;
wp_reset_postdata();
endif;
Після secondary loop не забудьте wp_reset_postdata(), щоб повернути глобальний контекст поточного запису.
4. Цикл через get_posts() — для невеликого списку постів
get_posts() повертає масив записів, який зручно обійти через foreach. Це підходить для блоків «останні новини», «ще по темі» або «схожі статті».
<?php
global $post;
$featured_posts = get_posts(
array(
'numberposts' => 5,
'category' => 7,
'orderby' => 'date',
'order' => 'DESC',
)
);
foreach ( $featured_posts as $post ) :
setup_postdata( $post ); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach;
wp_reset_postdata();
5. pre_get_posts для зміни головного циклу
Якщо потрібно змінити саме головний запит — наприклад, показувати на блозі 12 записів або приховати рубрики — не треба використовувати query_posts(). Зробіть це через хук pre_get_posts.
<?php
add_action( 'pre_get_posts', function ( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_home() ) {
$query->set( 'posts_per_page', 12 );
$query->set( 'category__not_in', array( 1, 2, 3 ) );
}
} );
Цей код втручається на етапі налаштування запиту до бази даних, тому є чистішим і передбачуванішим варіантом.
6. rewind_posts() для повторного проходу по тому самому loop
Іноді не потрібен другий SQL-запит. Наприклад, можна спочатку вивести зміст із заголовків, а потім повний контент тих самих записів. Для цього поверніть покажчик на початок через rewind_posts().
<?php if ( have_posts() ) : ?>
<ul class="post-toc">
<?php while ( have_posts() ) : the_post(); ?>
<li><a href="#post-<?php the_ID(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; ?>
</ul>
<?php rewind_posts(); ?>
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID(); ?>">
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
</article>
<?php endwhile; ?>
<?php endif; ?>
Що обирати на практиці
| Задача |
Що краще використати |
| Вивести головний архів або блог |
Стандартний loop |
| Змінити головний запит сторінки |
pre_get_posts |
| Створити додатковий блок записів |
WP_Query |
| Вивести короткий список постів |
get_posts() |
| Повторно пройти ті самі результати |
rewind_posts() |
| Legacy-код зі старих тем |
query_posts() лише з розумінням ризиків |
Підсумок
Для головного циклу найкраще покладатися на стандартний loop або змінювати його через pre_get_posts. Для додаткових блоків майже завжди найкращим рішенням буде WP_Query, для простих списків — get_posts(), а для повторного виводу тих самих результатів — rewind_posts().
Найважливіший висновок: у новому WordPress-коді тримайтеся ближче до WP_Query, pre_get_posts і стандартного main loop.