vendredi 25 septembre 2026

À propos

Contact

Thèmes

Pagination d’archives dans un thème : the_posts_pagination ou paginate_links

Quand utiliser chaque fonction, comment paginer une WP_Query secondaire, et pourquoi le paged casse sur la page d'accueil statique.

Par Clément Hadrot • 9 avril 2021 • 5 min de lecture • Aucun commentaire
Pagination d'archives dans un thème : the_posts_pagination ou paginate_links

La pagination d’archives paraît un détail mineur jusqu’au jour où elle casse silencieusement sur la page d’accueil d’un site qui utilise une page statique plutôt que les derniers articles. C’est exactement ce qui est arrivé sur le site de la librairie du Marais : la pagination des articles de blog, affichée sur une page dédiée nommée « Actualités », renvoyait systématiquement à la première page quel que soit le numéro cliqué. Cette recette détaille les deux fonctions de pagination du cœur de WordPress, leurs usages respectifs, et le piège précis rencontré sur ce projet.

Deux fonctions se disputent ce rôle : the_posts_pagination(), pensée pour la boucle principale, et paginate_links(), plus bas niveau et adaptée à n’importe quelle WP_Query secondaire.

the_posts_pagination pour la boucle principale

Sur un fichier de gabarit comme archive.php ou index.php, tant que la boucle utilise la requête principale générée automatiquement par WordPress, the_posts_pagination() reste la solution la plus simple :

the_posts_pagination( array(
	'mid_size'  => 2,
	'prev_text' => __( 'Précédent', 'agence' ),
	'next_text' => __( 'Suivant', 'agence' ),
	'screen_reader_text' => __( 'Navigation entre les pages', 'agence' ),
) );

Cette fonction lit automatiquement $wp_query, calcule le nombre total de pages et génère un balisage <nav> déjà pourvu d’un aria-label correct. Elle fonctionne sans configuration supplémentaire tant qu’on reste dans le contexte de la requête principale.

L'essentiel à retenir : the_posts_pagination pour la boucle principale ; paginate_links pour une WP_Query secondaire ; page_query_var indispensable avec une page d'accueil statique

Dès qu’une boucle personnalisée entre en jeu — par exemple une liste d’articles filtrée par catégorie affichée dans un template part, indépendante de la requête principale — the_posts_pagination() ne fonctionne plus correctement, car elle continue de lire $wp_query et ignore la requête secondaire. Il faut alors construire soi-même les liens avec paginate_links() :

$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;

$custom_query = new WP_Query( array(
	'category_name' => 'romans',
	'paged'          => $paged,
	'posts_per_page' => 6,
) );

$links = paginate_links( array(
	'total'   => $custom_query->max_num_pages,
	'current' => $paged,
	'type'    => 'array',
) );

if ( $links ) {
	echo '<nav class="c-pagination" aria-label="' . esc_attr__( 'Pagination des romans', 'agence' ) . '">';
	echo '<ul>';
	foreach ( $links as $link ) {
		echo '<li>' . $link . '</li>';
	}
	echo '</ul>';
	echo '</nav>';
}

Le paramètre 'type' => 'array' retourne chaque lien sous forme d’élément de tableau plutôt qu’une chaîne HTML brute, ce qui permet de les envelopper individuellement dans des <li> pour une liste sémantiquement correcte.

Le piège du paged sur une page d’accueil statique

Voici précisément le problème rencontré sur le site de la librairie. Quand le réglage « Vos derniers articles » sous Réglages > Lecture pointe vers une page statique dédiée (ici « Actualités »), la variable de requête à utiliser pour la pagination n’est plus paged mais page — utilisée normalement pour découper le contenu d’une page longue avec la balise <!--nextpage-->. WordPress résout ce conflit potentiel avec le paramètre page_query_var disponible dans certains contextes, mais surtout en vérifiant systématiquement la bonne variable selon le type de page :

$paged = get_query_var( 'page' ) ? get_query_var( 'page' ) : get_query_var( 'paged' );
$paged = $paged ? $paged : 1;

Cette double vérification résout le blocage constaté : sur une page d’accueil statique affichant les articles, WordPress route la pagination via page et non paged, une nuance qui ne saute pas aux yeux tant qu’on ne l’a pas rencontrée en production.

Vérifier l’accessibilité du résultat

  • La navigation doit être encadrée par une balise <nav> avec un aria-label explicite.
  • La page actuellement affichée doit porter un attribut aria-current="page" sur son lien.
  • Les liens « Précédent » et « Suivant » doivent rester présents mais désactivés visuellement en début et fin de liste, jamais simplement masqués sans explication.

Une pagination qui fonctionne sur l’archive de blog standard et casse sur une page d’accueil personnalisée n’est pas un cas limite exotique : c’est une configuration extrêmement courante chez les clients qui veulent une page d’accueil éditorialisée.

Notre verdict

the_posts_pagination() convient à la grande majorité des gabarits classiques tant que la requête principale suffit. Dès qu’une boucle personnalisée ou une page d’accueil statique entre en jeu, paginate_links() combiné à une vérification explicite de page et paged reste la solution la plus fiable. Le chargement infini en AJAX, souvent proposé comme alternative, pose ses propres questions d’accessibilité et de référencement qui méritent un article séparé.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi