Tout savoir sur WordPress
Tutoriel WordPress

Pagination WordPress sans plugin

L’un des rares défauts de WordPress est son système de pagination trop basique. Découvrez comment proposer à vos visiteurs une pagination digne de ce nom sans plugin !

WordPress n’a pas que des qualités.
Oui la réalité est difficile et l’un de ses plus grands défauts est son système de pagination classique (bouton suivant et précédent).

Sans plugin et avec seulement quelques lignes de codes, nous allons créer un système de pagination facilement intégrable à votre thème.

Pour l’exemple de notre tutoriel, le plugin recommandé par les « experts » WordPress est WP-Pagenavi. Ce plugin va installer deux dossiers et plus de 15 fichiers ! Un peu lourd pour un plugin censé proposer une navigation simple.

Placer le code suivant dans le fichier functions.php présent à la racine de votre thème  :

if( !function_exists( 'theme_pagination' ) ) {
	
    function theme_pagination() {
	
	global $wp_query, $wp_rewrite;
	$wp_query->query_vars['paged'] > 1 ? $current = $wp_query->query_vars['paged'] : $current = 1;
	
	$pagination = array(
		'base' => @add_query_arg('page','%#%'),
		'format' => '',
		'total' => $wp_query->max_num_pages,
		'current' => $current,
	        'show_all' => false,
	        'end_size'     => 1,
	        'mid_size'     => 2,
		'type' => 'list',
		'next_text' => '»',
		'prev_text' => '«'
	);
	
	if( $wp_rewrite->using_permalinks() )
		$pagination['base'] = user_trailingslashit( trailingslashit( remove_query_arg( 's', get_pagenum_link( 1 ) ) ) . 'page/%#%/', 'paged' );
	
	if( !empty($wp_query->query_vars['s']) )
		$pagination['add_args'] = array( 's' => str_replace( ' ' , '+', get_query_var( 's' ) ) );
		
	echo str_replace('page/1/','', paginate_links( $pagination ) );
    }	
}

Maintenant, tout ce que vous devez faire est d’ajouter la fonction vers le bas des pages où vous voulez que votre pagination doit apparaître. Si votre thème utilise le fichier loop.php, tout ce que vous devez faire est d’ajouter le code ci-dessous à la fin de votre boucle. Sinon, vous pouvez l’ajouter à index.php, archive.php et autres fichiers qui nécessitent la pagination.
<?php theme_pagination(); ?>

Explication sur les réglages :

  • end_size : détermine le nombre de liens a afficher en début et fin de la pagination
  • mid_size : détermine le nombre de pages a afficher avant et après la page courante

Si vous avez choisi une valeur de 3 pour mid_size, cela signifie que vous aurez toujours 3 pages (ou chiffres) de chaque côté de la page courante.

Pour plus d’informations sur les réglages de la fonction paginate_links(), cliquez sur ce lien.

Cet article a été mis à jour il y a 2446 jours - Il n'est peut être plus à jour !

Article écrit par Jonathan B.

Jonathan est le co-fondateur de WP Media, startup connue pour être l’auteur de WP Rocket et Imagify. Il est aussi co-organisateur du WordCamp Lyon et Paris.

105 Commentaires

  1. Attention ligne 8, il y a une erreur d’interprétation, le code a mettre est :
    if( empty( $paged ) ) et non pas if( emptyempty( $paged ) )

  2. Je suis moi aussi étonné par la lourdeur excessive de certains plugins par rapport aux fonctionnalités qu’ils sont censés ajouter. La même chose s’observe également avec les thèmes.

  3. Hello, merci pour le plugin, je suis d’accord avec la lourdeur de certains plugins…mais ce morceaux de code on le mets ou? bonne l’idée mais sans un minimum d’explications on zappe votre site..

    • Le contenu de la fonction theme_pagination se met dans le fichier functions.php.

      Ensuite, pour afficher la pagination dans un template, il suffit d’appeler la fonction !

  4. j’aimerais savoir dans quelle partie on insère ce code, car il me provoque une erreur dès que je l’intègre dans la page function.php

    • Je viens de mettre à jour l’article en apportant des explications sur la mise en place du code et j’ai aussi simplifié le code de la pagination.

  5. La taille du code et le nombre de fichiers pour un plugin ne veut absolument pas dire qu’il aura de mauvaises performances… ou qu’il consommera de la mémoire, ça ne veut rien dire…

    On peut consommer énormément de mémoire avec 1 fichier, et 3 lignes de PHP…

    Bref, tout ça pour dire que WP-PageNavi est plugin, et donc contrairement à une fonction du thème, il propose des options dans la console d’administration, il supporte l’internationalisation et différents modes d’affichage.

    Et puis pagenavi reste le plugin de référence, utilisé par un nombre incroyable de thèmes… pourquoi se faire du mal à alourdir son thème avec une fonction en plus :)

    • Après réflexion, je suis d’accord que ma remarque sur la performance n’est pas pertinente.

      Par contre répondre à votre dernière phrase, je suis programmeur et quand j’ai une alternative simple à ma disposition qui permet de faire la même chose qu’un plugin, je la choisirai.

      Pourquoi ? J’économiserai de la place dans ma base de données sans les paramètres pour ce plugin. Alors oui, on économise qu’une ligne dans notre table, mais c’est mon côté trop perfectionniste (ou chiant ^^) qui parle.

      Par contre, si nous ne sommes pas programmeur et qu’on a peur d’aller mettre les mains dans le code, il faut utiliser les plugins :)

      PS : je n’ai rien contre les plugins (oui, je disais le contraire dans mon article ^^) et j’ai réalisé il y a quelques jours un plugin de pagination car je trouvais WP-PageNavi incomplet sur quelques points.

      http://wordpress.org/extend/plugins/simple-pagination/

  6. Merci pour le tuto.

    comment fait on pour installer un système de pagination pour les commentaires quand on a plusieurs pages.

  7. bonjour,

    aucun de ces codes -celui-ci et la colorisation des articles – ne fon,ctionne: j’ai cette erreur, traduite en french :

    Impossible de redéclarer theme_pagination () (précédemment déclarés dans …/wp/wp-content/themes/mandigo/functions.php: 187) in …/wp/wp-content/themes/mandigo/functions.php sur la ligne 185.
    Même style d’erreur sur la colorisation.
    D’où celà vient-il ?
    Bonne journée.

    • C’est erreur indique que vous avez deux fonctions qui s’appelent theme_pagination dans votre fichier functions.php

      Hors deux fonctions ne peuvent pas avoir le même nom sinon ça fait l’erreur que vous indiquez.

    • Regardez les indications de votre erreur, tout est détaillé.

      Vous avez deux fois la déclaration de la fonction theme_pagination, ligne 185 et 187 dans votre fichier functions.php

  8. Bonjour,

    J’ai bien fait la manip, mais ma pagination n’apparait pas.

    J’ai mis dans les fichiers index.php archive.php le code
    Puis dans fonction le code que tu donnes plus haut.

    J’ai le thème Mystique 3.2.1 si ca peut te donnéer un idée.

    Merci

    • Bonjour jonathan,

      Je n’ai pas de fichier loop.php dans mon thème.
      Je l’ai donc inséré dans mon fichier index.php de mon thème et ainsi que archive.php. et rien.

      Par contre j’ai 3 fichiers dans un dossier du thème qui ce nome :

      loop-forums.php
      loop-replies.php
      loop-topics.php

      Et c’est tout.

      Merci pour ton aide.

  9. il y a un double !emptyempty ligne 23 de ton code, il faut juste !empty ;)

    merci en tout cas ca m’evite de reflechir :D

  10. Cool, merci

    A tout hasard, vu que l’affichage des pages est chronologique, j’aurais aimé inverser la pagination pour obtenir ceci

    << précédente 9 8 7 … 3 2 1

  11. Mauvaise réponse :-D

    Je n’ai pas l’impression que ce soit faisable simplement, peut être en utilisant le résultat sous forme de tableau et en inversant tout mais …. pas pour moi ça

    Merci

  12. Bonsoir,
    j’ai utilisé 2 systèmes de pagination sans plugin et les 2 me donnent la même « erreur ».
    Sur mon index.php la pagination fonctionne mais pas sur mes catégories.
    C’est à dire que monsite.com/page/2 fonctionne et monsite.com/wordpress/page/2 ne fonctionne pas.
    J’ai mis en préfixe de catégorie dans les permaliens « . » afin de ne pas avoir /category/ Serait ce lié à cela ?
    Merci d’avance :)

  13. « J’ai mis en préfixe de catégorie dans les permaliens « . » afin de ne pas avoir /category/ Serait ce lié à cela ? »

    Il faut tester pour être sûr :)

  14. Ca ne marche pas lorsque je mets ça query_posts( ‘cat=-1’ );
    Si je l’enlève ça fonctionne bien, sauf que là je veux exclure une catégorie de la page d’accueil, je fais comment pour paginer du coup ?

  15. @Chirstophe : C’est que tu as mal configurer query_posts ou que tu n’as pas assez d’articles pour avoir une pagination.

  16. Bonjour Jonathan
    J’ai installé ton plugin Simple Pagination qui est vraiment très bien. La liste des pages s’affiche bien là où je veux, toutefois quand je clique pour aller à la page suivante ou changer de page, il ne se passe rien, ça reste sur la première page. Tu as une idée ?
    Merci, Julie

  17. La fonction paginate_links ne fait pas d’exception pour la première page, qui devient donc accessible par deux URLs. Pas très propre + Duplicate Content pour Google. Exemple /ma_premiere et /ma_premiere/page/1/

    Ci-dessous la manière dont j’ai contourné le problème, si quelqu’un a une solution plus smart, je suis preneur !

    $tmp = paginate_links( $pagination );
    $tmp = str_replace("page/1/", "", $tmp);
    echo $tmp;
    
  18. @202 Ecommerce : C’est une très bonne remarque ! En effet, on se retrouve avec un Duplicate Content :/

    J’ai modifié le code de l’astuce. On peut simplifier directement le code par

    echo str_replace('page/1/','', paginate_links( $pagination ));
    
  19. Bonjour,
    j’ai tout bien fait, je n’ai pas d’erreur, j’ai même personalisé les numéros de pages… Par contre quand je clique sur la page 2 par exemple, il me rafraichit juste la page… Pour info, j’utilise un thème que j’ai développé de A à Z donc il manque peut-être des fonctions, ou je ne sais pas! La fonction est bien appelée dans le loop (avant le endwhile et le endif). Merci d’avance pour votre aide!

  20. @jonathan Alors je ne sais même pas de quoi tu parles donc je pense que je ne l’ai pas fait! :) Peux tu me guider ou me dire comment faire? Merci!

  21. @Ana Difficile de débugger à distance ! Dans le source de la page, la cible du lien (a href=) est-elle correcte ? Une fois cliqué, l’URL intègre-t-elle le /page/2 ?

  22. Bonsoir,
    Je viens vers vous à cette heure tardive car après avoir essayé bien des codes de pagination, celui-ci m’avait enfin sauvée. (Merci donc).
    Problème, je viens de me rendre compte que la pagination en question ne fonctionnait pas pour la page search et ses résultats. L’URL devient alors http://monsite.com/page/2/?s=la_recherche et renvoie une 404.
    Pour les autres pages, l’URL devient http://monsite.com/category/nom_category/page/2/ et fonctionne parfaitement.
    Auriez-vous une piste ?

  23. Petite précision quand à mon message d’hier (qui a disparu, peut-être est-il en cours de modo…?) :
    Je fais tout à l’heure une recherche avec 1 mot sur mon site, et là, miracle, la pagination remarche. Perplexe je réessaye la recherche qui ne marchait pas la veille, et là, merdouille, ça ne marche pas…
    La différence c’est qu’hier j’ai recherché l’expression « en ligne » qui est traduit sur la première page de résultat « en+ligne » et sur les suivantes « enligne », d’où l’erreur… D’ailleurs si je corrige à la mano « http://nomdusite.com/page/2/?s=en+ligne », ça se passe très bien. Mais voyez-vous, curieusement j’aimerais autant qu’il le fasse tout seul…
    Une piste, une idée, une modif dans le code ci-dessus… ? Merci d’avance en tout cas.

  24. Bjr merci pour le code, comment le mettre dans single.php, ou taxonomy-term.php? vu que j’utilise pas un query la dedans mais directement la boucle while?
    En haut vous dites qu’il faudra configurer la loop avec le numero de la page courante, je pige pas, pouvez vous expliquer svp car dans la description du code vous n’avez pas mentionné ce passage.
    Mon cas >> la pagination s’affiche mais chaque lien rafraîchit la première page seulement.
    En tout cas merci pour le code.

  25. Bonsoir,
    le code fonctionne t’il avec les custom post type ? car sur la page blog posts_per_page est limité a 3 mais impossible d’avoir une pagination :s j’ai que deux chois limiter ou tout affiché :s

  26. c’est good j’ai trouvé la solution le total etait à 1 mais bon maintenant tout mes liens de pagiantion me renvoie vers la page d’accueil :s

  27. Bonjour bon apres réflexion j’ai pu trouver ce qui bloqué dans le code la pagination fonctionne donc pour la homepage chaque article a un theme mais quand je veux naviguer dans mon theme j’ai se genre d’url : /blog/?theme=marketing-digit/page/2/ j’ai pas de message erreur mais il ya que le header et footer qui charge quelqu’un à une piste?
    merci pour votre aide

  28. @Jonathan merci pour ta réponse. oui mais quand je tape mon code en brute dans l’url comme ça il me dis que la page existe pas erreu 404 :s j’essai de bidouiller ton code pour rajouter une rewrite pour les themes

  29. @Macko : Ca ne risque pas de fonctionner avec ce genre d’URL /blog/?theme=marketing-digit/page/2/ il faudrait avoir quelque chose comme /blog/marketing-digit/page/2/

  30. bon la réecriture mais juste fait perdre 2h :s mais j’ai trouvé le code et sa marche partout :)
    query_vars[‘paged’] > 1 ? $current = $the_query->query_vars[‘paged’] : $current = 1;
    $big = 999999999;

    return paginate_links( array(
    ‘base’ => @add_query_arg(‘paged’,’%#%’),
    ‘format’ => ‘?paged=%#%’,
    ‘current’ => $current,
    ‘total’ => $the_query->max_num_pages,
    ‘prev_next’ => false
    ) );
    }

    the_query a la base c’est wp_query donc attention

  31. @Jonathan peux tu donner quelque commentaire sur ces lignes stp j’ai compris que c’est la que se passe la réécriture mais je ne comprends pas toute la logique merci if( $wp_rewrite->using_permalinks() )
    $pagination[‘base’] = user_trailingslashit( trailingslashit( remove_query_arg( ‘s’, get_pagenum_link( 1 ) ) ) . ‘page/%#%/’, ‘paged’ );

    if( !empty($wp_query->query_vars[‘s’]) )
    $pagination[‘add_args’] = array( ‘s’ => str_replace( ‘ ‘ , ‘+’, get_query_var( ‘s’ ) ) );

    echo str_replace(‘page/1/’, », paginate_links( $pagination ) );

  32. Re!!! Bon bon j’ai TOUT recommencé mon thème. J’ai bien ajouté le code dans functions.php. J’ai ajouté dans ma page page-blog.php (page ou sont mes articles à paginer) ceci :

    Avant le loop :
    $paged = (get_query_var(‘paged’)) ? get_query_var(‘paged’) : 1;
    query_posts(‘category_name=Blog&posts_per_page=5&paged=’ . $paged);

    Après endwhile et avant endif
    php theme_pagination();

    (j’ai enlevé les balises php)

    après tout ce qui est the_content() etc…

    J’ai pas de pagination qui s’affiche. J’ai que mes 5 articles sur ma page et rien pour naviguer. Donc j’ai pas de message d’erreur ni rien vu que j’ai rien! Merci pour votre aide précieuse.

  33. Bonjour;
    Comment peut-on écrire du code sur le blog et qu’on aura l’impression que c’est fait sur un éditeur de type sublime text2 (comme dans votre article).
    Merci d

  34. @Koceila : Ce n’est pas vraiment le sujet de l’article… Mais vous pouvez aller voir du côté de Google Prettify.

  35. Bonsoir,

    Super code.
    Par contre comment faire pour récupérer le numéro de page afin de l’intégrer dans la balise Title ?
    Via le plugin Yoast WordPress SEO !

    Merci

  36. @dZiGue : Il faut utiliser le tag %%page%% dans la configuration des titles avec WordPress SEO :)

  37. @dZigue : Alors c’est peut-être %%pagenumber%%. Les tags de WordPress SEO sont disponibles dans l’onglet « Aide » ^^

  38. en fait ça marche en virant le showpost ou le posts_per_page par contre comment on gère le style (css) de cette pagination. Chez moi ca me fait un truc pourri …
    merci

  39. Bonjour ce code est ce que je recherche mais il ne marche pas pour les pages ‘category’ . Une idée ? J’ai essayé tt ce que j’ai pu voir, sans succès…

    Merci

  40. C’est à dire ? où les définir ?
    désolé de faire mon relou mais je suis en galère la :s

    (ps skoop et devenir c’est la même personne, moi …)

  41. @ skoop: Bin dans le fichier CSS de votre thème, je ne peux pas être plus précis, désolé…

  42. oui je sais mais quels sont les objets paramétrables ?
    Est ce que je dois modifier div,ul ? class=pagination, page ou autre ?

    Merci

  43. Merci pour cet article, très complet.
    @ skoop; Je sais pas si tu as réussi à modifier le css de ta pagination.

    Ci-dessous un exemple de code à insérer dans le fichier css de ton thème :

    ul.page-numbers {float: right; margin-right: 20px;}
    .page-numbers li {display: inline; list-style: none;}
    .page-numbers a, .page-numbers span {margin: 2px 6px; padding: 5px 10px; background-color: #4fc1e1; border-radius: 3px 3px 3px 3px; color: #fff; box-shadow: 1px 1px 3px #555555; transition-duration: 0.3s;}
    .page-numbers a:hover, .page-numbers span.current {background-color: #ea2e79;}
    
  44. Bonjour,

    Merci pour la fonction. Par contre (et c’est bizarre que personne ne l’ai signalé), chez moi j’ai été obligé de changer la ligne :

    ‘base’ => @add_query_arg(‘page’,’%#%’),

    Par

    ‘base’ => @add_query_arg(‘paged’,’%#%’),

    Sinon je restais éternellement sur la page 1 ;)

    Nouveauté de WordPress 3.7 ?

  45. C’est déjà une piste surtout que tous les code de ce genre (pagination) me fait la méme chose.
    Sais tu la ligne a vérifié ? même si c’est pas le sujet ?

  46. @wilfried18: Il faut modifier le fichier style.css du thème. Mais après, je ne peux pas en dire plus car ça sera en fonction de votre design.

  47. bonjour,
    excusez moi mais on met quoi comme CSS, là j’ai toujours la numérotation en verticale et non en horizontale, merci

  48. @soulfree: Désolé, mais le sujet de l’article et du blog n’est pas le CSS. Je vous recommande de poser cette question sur un forum dédié à une communiqué HTML/CSS :)

  49. Je suis réservé sur la ligne `str_replace(‘page/1/’, », paginate_links( $pagination ));` qui certes peut éviter un « double-lien » vers la page 1 quand on affiche l’ensemble des posts (si le thème prévoir un lien vers la racine quelque part ; dans le titre par exemple).

    Mais si on affiche les posts relatifs à une catégorie, un tag, ou suite à une recherche, …, il est nécessaire de garder le lien vers la page 1 de cette requête.

  50. J’ai le même problème que devock, mais sa solution ne fonctionne pas pour moi.
    J’ai le même avis qu’Izno, mais …..pas de solution :)

  51. bonsoir,
    pas reçu la notification j’ai du oublier de cocher
    « Prévenez moi de tous les nouveaux commentaires par email. »

    Je sais que l’on n’est pas sur un site de CSS mais j’ai déjà vu sur d’autres sites donné des codes et mettre la partie CSS, j’ai fini pas réussi grâce à un article ailleurs ou tout est donné, code functions.php, code à mettre pour appeler la pagination et le CSS.
    De plus le code ne fonctionnait pas ici, je rrestait bloqué su la 1er page alors que utilise Twenty Twelve par défaut sans rien changer.

  52. Bsr
    pour moi, la pagination n’apparait pas dans la page index ,mais dans les autres pages ça marche bien , je ne sais pas pourquoi , scp aide moi ,j’ai perdu beaucoup de temps a trouver la solution mais je n’ai pas arrivé

  53. @adam: Il faut vérifier que le query_posts ou le WP_QUery() soit bien paramétré dans votre page d’accueil

  54. Bonjour merci pour ce tuto,

    j’ai utilisé le plugin nextgen gallery pour la gestion de mes images. J’ai des albums avec plusieurs galeries et je voudrais mettre une pagination sur les galeries des albums. Je me demande si c’est possible avec ce code?

  55. Bonjour, souhaitant mettre en place une pagination sur mon site, j’ai insérer votre code ds fonctions.php … mais maintenant il se trouve que je me retrouve avec deux pages blanches. Une pour mon admin sur wordpress et l’autre pour visualiser mon blog. Comment faire pour récupérer mon admin et blog ? en sachant que j’ai effacé votre code et remis celui de la pagination du thème. Merci.

  56. Super tuto toujours d’actualité. J’ai galère pendant un moment pour le faire marcher dans les pages catégories, puis j’ai viré le post per page dans le querie et bingo ! :) Merci.

  57. Bonjour,

    Merci pour le tuto qui permet de ne pas utiliser de plugin.

    J’ai suivi le tuto mais cela ne fonctionne pas, la pagination s’affiche bien mais quand je clique sur suivant l’url est bien « monsite.com/page/2/ » mais le contenu est celui de la page 1 et la pagination est actif encore sur le 1.

    J’utilise wordpress en multisite et un theme perso où il y a pas beaucoup de code.

    voici le code que j’ai mis dans fonction :

    if(!function_exists(‘pagination_options’)){
    function wp_pagination(){
    global $wp_query, $wp_rewrite;
    $wp_query->query_vars[‘paged’] > 1 ? $current = $wp_query->query_vars[‘paged’] : $current = 1;

    $paginations = array(
    ‘type’ => ‘list’,
    ‘prev_text’ => ‘ ‘>’,
    );

    if($wp_rewrite->using_permalinks())
    $paginations[‘base’] = user_trailingslashit(trailingslashit(remove_query_arg(‘s’, get_pagenum_link(1))) . ‘page/%#%/’,’paged’);

    if(!empty($wp_query->query_vars[‘s’]))
    $paginations[‘add_args’] = array(‘s’ => str_replace(‘ ‘ ,’+’,get_query_var(‘s’)));

    echo  » . str_replace(‘page/1/’, », paginate_links($paginations)) .  »;
    }
    }

    Cela fait une semaine que je penche dessus je n’arrive pas a trouver l’erreur.

    Merci

  58. Bonjour,

    @devock,

    En effet, le code ne fonctionne pas si on utilise das permaliens standards.

    Il faut modifier
    if( $wp_rewrite->using_permalinks() )
    $pagination[‘base’] = user_trailingslashit( trailingslashit( remove_query_arg( ‘s’, get_pagenum_link( 1 ) ) ) . ‘page/%#%/’, ‘paged’ );

    par le code suivant :
    if( $wp_rewrite->using_permalinks() ){
    $pagination[‘base’] = user_trailingslashit( trailingslashit( remove_query_arg( ‘s’, get_pagenum_link( 1 ) ) ) . ‘page/%#%/’, ‘paged’ );
    }else{
    $pagination[‘base’] = user_trailingslashit( trailingslashit( remove_query_arg( ‘s’, get_pagenum_link( 1 ) ) ) . ‘?paged=%#%/’, ‘paged’ );
    }

    Tout en conservant
    ‘base’ => @add_query_arg(‘page’,’%#%’),

  59. Bonjour!
    est-ce possible d’utiliser ce fonction pour faire une pagination pour une liste d’articles dans un sidebar (« widget »)…?

    • @my: À ce jour, je vous conseillerai plutôt d’utiliser un plugin comme WP-PageNavi.

2e9fe150537e293a4c80cab43c4a4677CCCCCCCCC