Paginacja na stronach internetowych pozwala poruszać się po postach i podzielić obszerne listy postów (lub innych obiektów) na wiele mniejszych podstron. W tak dojrzałym i zaawansowanym systemie CMS jakim jest WordPress oczywiście nie może zabraknąć wbudowanego mechanizmu paginacji.
Jako twórcy motywów możemy używać prostych linków lub numerowanej paginacji, aby wskazać poprzednią lub następną stronę w danej kolejności. WordPress ma możliwość dzielenia pojedynczego posta lub listy postów na wiele stron w celu nawigacji na numerowanych podstronach. Co ciekawe, niektóre ustawienia dotyczące paginacji znajdziemy w standardowych Ustawieniach. Liczbę wpisów do wyświetlenia na każdej stronie można dostosować na ekranie Ustawienia > Czytanie.

Decyzja o tym czy motyw będzie respektował te wartości ostatecznie jest w naszych rękach kiedy tworzymy motyw. Wartość wpisaną w polu „Strony bloga wyświetlają maksymalnie” można pobrać za pomocą:
get_option('posts_per_page')
i użyć jej w niestandardowych zapytaniach. Gdy w szablonie używamy wiele pętli (list postów), tylko jedna pętla – ta główna – może być podzielona na strony.
Paginacja pętli WordPress (listy postów)
Tworząc motyw od zera podstawowa pętla zwracająca listę wpisów w szablonie home.php wygląda mniej więcej tak:
<?php global $post; $myposts = get_posts(); foreach ( $myposts as $post ) : setup_postdata( $post ); ?> <a href="<?php the_permalink(); ?>"><h2><?php the_title(); ?></h2></a> <?php endforeach; wp_reset_postdata(); ?>
Żadna paginacja nie zostanie wyświetlona a WordPress zwróci nam 5 postów. aby otrzymać ilość postów według ustawień WordPressa musimy użyć wspomnianej wcześniej zmiennej:
<h1>Lista postów</h1> <?php global $post; $args = array( 'posts_per_page' => get_option('posts_per_page') ); $myposts = get_posts( $args ); foreach ( $myposts as $post ) : setup_postdata( $post ); ?> <a href="<?php the_permalink(); ?>"><h2><?php the_title(); ?></h2></a> <?php endforeach; wp_reset_postdata(); ?>
W takim wypadku też na próżno szukać paginacji. Musimy ładnie poprosić WordPressa aby dodał paginację. Służy do tego funkcja:
<?php echo paginate_links(); ?>
Linki co prawda się generują i odsyłają do podstron /page/2/ page/3/ itd. ale w żaden sposób nie wpływa to na zawartość listy. Lista postów „nie wie”, czy jest generowana na pierwszej czy kolejnej podstronie aby mechanizm przełączania stron działał musimy wyciągnąć numer z adresu URL i przekazać go do argumentów pętli. Do argumentów dojdzie nam parametr paged:
$args = array( 'posts_per_page' => get_option('posts_per_page'), 'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 ) );
Jak widać teraz wszystko działa jak należy. Funkcja paginate_links() może przyjmować wiele argumentów, które pozwalają dostosować jak dokładnie linki do kolejnych podstron mają być generowane. W jednej z realizacji zamiast słów Poprzednie / Następne wyświetliłem ikony strzałek:
paginate_links( array( 'prev_text' => '<i class="icon-arrow-left"></i>', 'next_text' => '<i class="icon-arrow-right"></i>' ));
W kolejnej z realizacji nadałem poszczególnym elementom klasy znane z Bootrstrapa pobierając paginację w formie tablicy i używając prostych operacji na ciągach znaków:
$pagination = paginate_links( array( 'type' => 'array' )); <nav> <ul class="pagination justify-content-center"> <?php foreach($pagination as $key => $value): ?> <li class="page-item <?php if (strpos($value, "current") !== false) { echo "active"; } ?>"><?php echo str_replace("page-numbers","page-numbers page-link", $value); ?></li> <?php endforeach; ?> </ul> </nav>
Tworząc niestandardowe pętlę z własnymi argumentami lub kiedy dodajemy nawigację do niestandardowych szablonów typu page.php, należy przekazać argument total w funkcji paginate_links(). Musimy ten argument przekazać aby funkcja paginate_links() wygenerowała odpowiednią ilość linków z paginacją. To częsty przypadek kiedy tworzymy paginację dla niestandardowych typów postów WordPress:
$loop = new WP_Query( $args ); echo paginate_links( array( 'total' => $loop->max_num_pages ));
Częste problemy z paginacją WordPress
Warto w tym momencie wspomnieć o częstych problemach z paginacją. Jednym z najczęstszych problemów jest fakt, że nie działa ona na stronach front-page.php. Cały ten przykład użycia paginacji po prostu się zepsuje kiedy cały szablon zapiszemy jako na przykład front-page.php a w ustawieniach WordPressa wybierzemy opcję, która wyświetla statyczną stronę jako stronę główną.
Paginacja może mieć duży wpływ na SEO witryny. Pamiętaj, że paginacja będzie tworzyć kolejne podstrony z unikalnymi adresami URL z niezbyt unikalną treścią. W pewnych sytuacjach warto rozważyć wyłączenie podstron paginacji z indeksu wyszukiwarki za pomocą noindex. Zwróć uwagę, że na stronach tego typu rotują posty w tempie odpowiadającym temu jak często dochodzi do publikacji nowych treści. Takie strony „rozwadniają” moc linkowania i mogą wprowadzać dużo zamieszania.
Poprzedni i następny post
Poprzedni i następny post, który zazwyczaj jest nam proponowany na końcu bieżącego artykułu to kolejny typ paginacji. Tutaj też nie ma zbyt wielkiej filozofii. Do generowania tego typu linków używa się gotowych funkcji get_previous_post() oraz get_next_post(). Czasami posty te nie istnieją a linkom towarzyszą napisy typu „Kolejny post”. Warto wówczas napisać prostą instrukcję warunkową:
<?php
$prev_post = get_previous_post();
if ( ! empty( $prev_post ) ): ?>
<span class="small">Poprzedni artykuł</span>
<a href="<?php echo get_permalink( $prev_post -> ID ); ?>">
<h3><?php echo $prev_post -> post_title; ?></h3>
</a>
<?php endif; ?>
Dla następnego postu kod będzie wyglądał tak:
<?php $next_post = get_next_post(); if ( ! empty( $next_post ) ): ?> <span class="small">Następny artykuł</span> <a href="<?php echo get_permalink( $next_post -> ID ); ?>"> <h3><?php echo $next_post -> post_title; ?></h3> </a> <?php endif; ?>
Dzielenie pojedynczego postu na części
Ostatni przykład paginacji to strony pojedynczego postu podzielonego na wiele części. W standardowym edytorze Gutenberg jest do tego odpowiedni blok o nazwie Podział strony:

WordPress wspiera tego typu rozwiązania także w klasycznym edytorze za pomocą specjalnego znacznika nextpage. Aby szablon obsługiwał taką paginację należy użyć funkcji:
wp_link_pages();
Stosunkowo rzadko trzeba kodować tego typu paginację (lub jest konsekwencją nieprzemyślanej architektury strony) ale warto o tym wiedzieć w przypadku nietypowych zleceń. Funkcja ta nie przyjmuje tylu argumentów co wp_paginate_links() i już parę razy zdarzyło mi się spotkać z tym, że deweloperzy omijają ten problem za pomocą wtyczki WP-PageNavi autorstwa Lester 'Gamerz’ Chan (ten sam deweloper, który stworzył wtyczkę WP-Sweep). Wówczas zamiast wp_link_pages() używamy funkcji:
wp_pagenavi( array( 'type' => 'multipart' ) );
Nie jestem zwolennikiem używania wtyczek do tak banalnych przypadków, ale warto o niej wiedzieć, bo jest bardzo popularna i może przydać się w sytuacji, kiedy klient chce odtworzyć jej funkcjonowanie w nowej wersji lub nalega aby wygląd paginacji był w pewnym stopniu możliwy do personalizacji z poziomu panelu WordPress jak dotychczas.
Podsumowanie
Jak widać WordPress z pudełka bez żadnych wtyczek udostępnia szereg wygodnych funkcji do wykonywania różnego rodzaju paginacji i podziału stron. Podział stron wpływa na UX i SEO a to jak wygląda i jak zachowuje się paginacja znacząco wpływa na estetykę i wygodę korzystania z serwisu. Zbyt mało elementów na jednej stronie zmusza użytkownika do męczącego klikania, mnoży automatycznie generowane strony i rozwadnia treść pod kątem SEO. Zbyt dużo elementów również powoduje problemy pod kątem UX i może mocno spowalniać ładowanie się strony internetowej. Jak zawsze warto celować w takie rozwiązania aby pogodzić wszystkie wymienione sfery jakości strony internetowej. Ciekawą alternatywą dla paginacji może być infinte-scroll, który w WordPressie można zakodować samemu lub skorzystać z istniejących wtyczek.
Źródła
- https://developer.wordpress.org/reference/functions/paginate_links/
- https://developer.wordpress.org/reference/functions/get_previous_post/
- https://developer.wordpress.org/reference/functions/get_next_post/
- https://developer.wordpress.org/reference/functions/wp_link_pages/
- https://codex.wordpress.org/Pagination
Odpowiedz lub skomentuj