4 sposoby ustawienia pętli Loop w WordPressie
Pętla Loop w WordPressie to serce wyświetlania treści w motywie. To właśnie przez nią WordPress przechodzi po znalezionych wpisach i podstawia do szablonu tytuł, link, zajawkę, treść, miniaturę, datę oraz inne dane. Historycznie najczęściej mówi się o czterech sposobach ustawienia loopa, ale w nowoczesnym WordPressie warto znać także nowsze i bezpieczniejsze podejścia.
W skrócie: klasyczne 4 metody to standardowy loop, query_posts(), WP_Query i get_posts(). W praktyce warto dodać do tego jeszcze pre_get_posts do modyfikacji głównego zapytania oraz rewind_posts() do ponownego przejścia po tych samych wynikach.
Jak loop działa wewnątrz WordPressa
Gdy użytkownik otwiera stronę, WordPress analizuje adres URL, buduje zestaw query vars, a następnie tworzy główne zapytanie. Na poziomie rdzenia odpowiada za to obiekt WP_Query, który pobiera wpisy z bazy danych i przechowuje je w swojej strukturze. Najczęściej dane pochodzą z tabeli wp_posts, a przy filtrowaniu po meta-polach, taksonomiach lub statusach dołączane są również inne tabele, na przykład wp_postmeta.
Następnie w szablonie działa znana konstrukcja have_posts() + the_post(). Pierwsza sprawdza, czy są jeszcze wpisy do pokazania, a druga przesuwa wskaźnik na kolejny rekord i przygotowuje globalny kontekst posta, aby template tags takie jak the_title(), the_content(), the_permalink() czy the_post_thumbnail() działały poprawnie.
Najprostszy standardowy loop wygląda tak:
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php the_excerpt(); ?>
</article>
<?php endwhile; ?>
<?php the_posts_pagination(); ?>
<?php else : ?>
<p>Nie znaleziono wpisów.</p>
<?php endif; ?>
To jest główna, domyślna pętla. Świetnie sprawdza się na blogu, archiwach, stronach kategorii, tagach czy wynikach wyszukiwania, czyli wszędzie tam, gdzie WordPress sam przygotował już właściwe zapytanie główne.
1. Standardowy loop — najlepszy start i najczęściej najlepszy wybór
W wielu motywach w ogóle nie trzeba tworzyć dodatkowych zapytań. Jeżeli pracujesz z index.php, home.php, archive.php, category.php, tag.php albo search.php, WordPress przekazuje do szablonu gotowy main query. Wystarczy go poprawnie wypisać.
Zaletą tego podejścia jest prostota: nie psujesz paginacji, nie dublujesz logiki rdzenia i nie tworzysz niepotrzebnych zapytań SQL. W wielu przypadkach to właśnie standardowy loop jest najbardziej eleganckim rozwiązaniem.
2. Pętla przez query_posts() — sposób historyczny, ale dziś niewskazany
Dawniej query_posts() było bardzo popularne, bo pozwalało szybko zmienić parametry głównej pętli bezpośrednio w szablonie. Można było w prosty sposób ograniczyć liczbę wpisów, wykluczyć kategorię albo zmienić sortowanie. Problem polega na tym, że ta funkcja nie tworzy nowego, bezpiecznego zapytania, tylko podmienia główny query.
<?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();
?>
Technicznie to działa, ale w praktyce łatwo narobić sobie problemów z paginacją, warunkami lub przewidywalnością działania szablonu. Dlatego w nowym kodzie lepiej unikać query_posts() i traktować je raczej jako rozwiązanie spotykane w starszych motywach.
Wskazówka: jeżeli potrzebujesz zmienić główne zapytanie strony, nowoczesnym i poprawnym podejściem będzie pre_get_posts, a nie query_posts().
3. Pętla przez WP_Query — główne narzędzie do własnych i dodatkowych zapytań
Klasa WP_Query to najbardziej uniwersalne narzędzie do tworzenia własnych pętli. Nie narusza głównego zapytania, tylko daje osobny obiekt z wynikami. Dzięki temu możesz budować kilka niezależnych bloków na jednej stronie: aktualności, polecane artykuły, case study, produkty, wpisy z konkretnej kategorii lub custom post types.
<?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(); ?>" <?php post_class('news-card'); ?>>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php the_excerpt(); ?>
</article>
<?php
endwhile;
endif;
wp_reset_postdata();
?>
Po zakończeniu takiej pętli trzeba zwykle wywołać wp_reset_postdata(), aby przywrócić globalny kontekst posta. To drobiazg, ale bardzo ważny, zwłaszcza jeśli po secondary loopie w tym samym szablonie ma jeszcze działać główna pętla lub template tags odnoszące się do bieżącego wpisu.
4. Pętla przez get_posts() — prosty sposób na krótki zestaw wpisów
Funkcja get_posts() jest wygodna wtedy, gdy potrzebujesz po prostu pobrać niewielką listę wpisów i przejść po niej w foreach. To częsty wybór dla bloków typu „ostatnie wpisy”, „powiązane artykuły” albo „polecane materiały w sidebarze”.
<?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();
?>
Zaletą get_posts() jest zwięzłość. Wadą — mniejsza przejrzystość przy bardziej rozbudowanych scenariuszach. Jeżeli potrzebujesz paginacji, złożonych filtrów lub kilku większych custom loops, lepszym wyborem będzie WP_Query.
5. Nowoczesne podejście: pre_get_posts do zmiany głównej pętli
To właśnie ta metoda powinna zostać dopisana do klasycznej listy „czterech sposobów”. Jeżeli chcesz zmienić główny query strony — na przykład liczbę wpisów na blogu, wykluczone kategorie albo kolejność wyników — nie musisz podmieniać pętli w szablonie. Dużo lepiej zrobić to wcześniej, na etapie budowania zapytania.
<?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));
}
});
Taki kod działa czyściej, bo nie nadpisuje gotowych wyników po fakcie, tylko modyfikuje parametry jeszcze przed wykonaniem zapytania do bazy danych. W nowoczesnym WordPressie to jedno z najlepszych rozwiązań do pracy z main query.
6. Dodatkowy trik: rewind_posts() do ponownego użycia tych samych wyników
Czasem nie potrzebujesz drugiego zapytania SQL. Jeżeli chcesz najpierw wypisać same tytuły, a potem niżej pełną treść tych samych wpisów, możesz po prostu przewinąć wskaźnik pętli z powrotem za pomocą rewind_posts().
<?php if (have_posts()) : ?>
<ul class="post-toc">
<?php while (have_posts()) : the_post(); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; ?>
</ul>
<?php rewind_posts(); ?>
<?php while (have_posts()) : the_post(); ?>
<article>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
</article>
<?php endwhile; ?>
<?php endif; ?>
To bardzo przydatny wzorzec, o którym wielu programistów zapomina. Dzięki niemu można budować bardziej złożone układy szablonu bez wykonywania kolejnego query.
Co wybrać w praktyce
| Zadanie |
Najlepszy wybór |
| Wyświetlenie głównego archiwum lub bloga |
Standardowy loop |
| Modyfikacja głównego zapytania strony |
pre_get_posts |
| Dodatkowy blok wpisów w szablonie |
WP_Query |
| Krótka lista wpisów w sidebarze lub widżecie |
get_posts() |
| Ponowne przejście po tych samych wynikach |
rewind_posts() |
| Stary kod w legacy theme |
query_posts() tylko świadomie |
Podsumowanie
Historycznie rzeczywiście mówi się o czterech sposobach budowania loopa w WordPressie: standardowym loopie, query_posts(), WP_Query i get_posts(). Ale z perspektywy nowoczesnego developmentu obraz jest szerszy. Dla głównego query najlepiej polegać na standardowej pętli albo modyfikować ją przez pre_get_posts. Dla bloków dodatkowych najczęściej najlepiej sprawdza się WP_Query. Dla prostych list wygodne jest get_posts(). A gdy trzeba jeszcze raz użyć tych samych wyników, bardzo dobrze działa rewind_posts().
Najważniejszy wniosek jest prosty: nie każda metoda jest dziś równie dobra. To, co kiedyś było normalne, jak query_posts(), dziś jest raczej częścią legacy WordPressa. Jeżeli chcesz pisać czysty i przewidywalny kod, trzymaj się standardowego loopa, WP_Query i pre_get_posts.