La pagination permet de répartir des résultats trop nombreux sur plusieurs pages.
SPIP propose donc un système simplifié de pagination des résultats d’une boucle.
Syntaxe de base
Au plus simple, ce système est composé d’un critère et d’une balise :
- le critère
{pagination}
s’ajoute sur la boucle à paginer ; - la balise
#PAGINATION
, placée dans une des parties optionnelles (« avant » ou « après ») de la boucle, affiche la « pagination ».
<B_page>
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]
<ul>
<BOUCLE_page(ARTICLES){par date}{pagination}>
<li>#TITRE</li>
</BOUCLE_page>
</ul>
</B_page>
Si le site comporte 90 articles publiés, cette boucle affichera la liste des dix plus anciens articles, surplombée de liens conduisant vers la page qui affiche les dix suivants, les dix d’après, etc. Ces liens sont numérotés comme suit :
Le numéro à partir duquel les résultats sont affichés est passé dans l’url via un paramètre {debut_page=x}
portant le même nom (ici, « page ») que la boucle concernée. (Ce paramètre est exploitable dans une autre boucle via le critère classique {debut_page,10}
.)
A noter : le nombre total de liens affichés est limité ; des points de suspension permettent, le cas échéant, d’aller directement à la toute fin de la liste, ou de revenir au tout-début.
Ancres de pagination
La balise #PAGINATION comporte une ancre HTML qui permet au navigateur d’afficher directement la partie de la page qui est paginée ; toutefois si l’on veut mettre les liens de pagination en dessous de la liste des articles, il faut pouvoir placer l’ancre au-dessus de la liste.
C’est à cela que sert la balise #ANCRE_PAGINATION, qui retourne l’ancre en question, et interdit à la balise #PAGINATION
suivante d’afficher son ancre.
<B_page>
#ANCRE_PAGINATION
<ul>
<BOUCLE_page(ARTICLES){par date}{pagination}>
<li>#TITRE</li>
</BOUCLE_page>
</ul>
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]
</B_page>
Inversement, pour ne pas ancrer, on précisera [(#ANCRE_PAGINATION|vide)]
dans la boucle.
Accès direct à un élément particulier
Pour permettre de donner une URL permanente vers un élément précis d’une liste paginée on utilisera &debut_abc=@xxx
où « abc
» est le nom de la boucle de pagination et « xxx
» l’id de l’objet dans la table sur laquelle porte la pagination.
Exemple : Dans une boucle
<B_pagi>
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]
<ul>
<BOUCLE_pagi(ARTICLES){par titre}{pagination}>
<li>#ID_ARTICLE : #TITRE</li>
</BOUCLE_pagi>
</ul>
</B_pagi>
&debut_pagi=10
place la pagination sur la deuxième page (à partir du dixième élément de la liste)&debut_pagi=@231
place la pagination sur la page qui contient l’id_article « 231 ».
Le nombre total de résultats
Dans une boucle avec le critère {pagination}
, #TOTAL_BOUCLE affiche le nombre d’éléments effectivement retournés, c’est-à-dire 10 sur les pages pleines, et 10 ou moins sur la dernière page de résultats.
Pour afficher le nombre d’éléments qui auraient été retournés si le critère {pagination}
n’avait pas été là, utilisez la balise #GRAND_TOTAL
.
<B_pagination>
#ANCRE_PAGINATION
<BOUCLE_pagination (ARTICLES) {pagination}>
#TITRE <br>
</BOUCLE_pagination>
Il y a au total #GRAND_TOTAL articles, cette page en affiche #TOTAL_BOUCLE
</B_pagination>
indiquera : « Il y a au total 1578 articles, cette page en affiche 10. »
Changer le pas de la {pagination}
Le nombre standard de 10 éléments par page peut être modifié par un paramètre supplémentaire dans le critère.
Ainsi
<BOUCLE_page(ARTICLES){pagination 5}>
#TITRE<br>
</BOUCLE_page>
retournera les titres de cinq articles à partir de debut_page.
Le paramètre en question peut lui-même être composé comme on le souhaite à partir d’autres balises, notamment #ENV{xx}
, ce qui permet de faire un affichage à la demande très complet.
La pagination dans les squelettes inclus
Si votre pagination doit fonctionner dans un squelette inclus, vous devez passer en paramètre de la commande INCLURE
la formulation {ajax, env}
; ceci permet au squelette inclus de se calculer avec la bonne valeur du paramètre debut_xxx, et se justifie qui plus est par un besoin de sécurité (la balise #PAGINATION
est en effet calculée à partir de l’URL complète de la page).
Nommer le critère de pagination
Lorsque l’on utilise des squelettes inclus plusieurs fois dans la même page comme :
<BOUCLE_incluse(ARTICLES){id_rubrique}{par titre}>
<INCLURE{fond=motsgroupe5,id_article,ajax,env}>
</BOUCLE_incluse>
et que cet INCLURE possède une pagination (d’où l’utilisation du critère {env}
), lorsque vous cliquerez sur une pagination, vous verrez toutes les paginations se modifier en même temps.
Pour éviter cela, il suffit de nommer le critère pagination à l’intérieur du fichier inclu par un nom qui sera différent à chaque inclusion :
<B_groupe5>
#ANCRE_PAGINATION
<BOUCLE_groupe5(MOTS){id_groupe=5}{pagination 15, #ID_ARTICLE}>
#TITRE<br>
</BOUCLE_groupe5>
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]
</B_groupe5>
On peut aussi vouloir spécifier dès l’appel de l’INCLURE le nom que l’on veut donner au critère pagination :
<INCLURE{fond=page_paginee, env, nom_p=_abc}>
<INCLURE{fond=page_paginee, env, nom_p=_def}>
dans page_paginee.html :
<B_a>
#ANCRE_PAGINATION
<BOUCLE_a(ARTICLES){pagination 25, #ENV{nom_p}}>
#TITRE<br>
</BOUCLE_a>
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]
</B_a>
Styles de la pagination
La pagination est constituée d’une série de liens, et d’un numéro de page correspondant à la page actuelle doté de la class « .on » : on définira donc les styles pour a et .on pour en personnaliser l’apparence.
Choisir le modèle de pagination
La balise #PAGINATION
accepte un paramètre {modele}
, qui permet de modifier le résultat de la balise.
#PAGINATION{precedent_suivant}
affichera des liens vers les pages précédentes et suivantes. Les liens seront les suivants
#PAGINATION{page}
affichera quelque chose de la forme suivante
#PAGINATION{page_precedent_suivant}
affichera quelque chose comme
page précédente 1 | 2 | 3 | 4 | 5 | 6 | page suivante
#PAGINATION{prive}
affichera quelque chose comme
0 | 10 | 20 | 30 | Tout afficher
Il est possible de définir d’autres modèles de pagination dans le dossiers modeles/
de votre jeu de squelettes. Ils devront s’appeler pagination_nomdumodele
. On pourra, pour les fabriquer, s’inspirer de ceux livrés de base avec SPIP et situés dans le répertoire prive/modeles/
Personnaliser le modèle de pagination
Chaque modèle possède des paramètres qu’il est possible de personnaliser.
Par exemple, #PAGINATION{page_precedent_suivant}
affiche par défaut :
page précédente 1 | 2 | 3 | 4 | 5 | 6 | page suivante
#PAGINATION{page_precedent_suivant, label_precedent=<, label_suivant=>}
affiche :
Configurer l’adresse des liens de #PAGINATION
À partir de SPIP 3.2.8, il devient possible de spécifier quelle URL doit servir de base pour les liens générés par la balise #PAGINATION
.
Par exemple, cela permet, si nécessaire, de nettoyer une variable d’URL indésirable :
#PAGINATION{prive,self=#SELF|parametre_url{...}}
Configurer le nombre de liens
Depuis SPIP 4.0, les différents modèles de pagination acceptent un paramètre nombre_liens_max
qui, passé a la balise #PAGINATION
permet de définir le nombre de lien de pagination maximum affiché par le modèle. On peut également employer la constante _PAGINATION_NOMBRE_LIENS_MAX
.
Définir un nouveau modèle de pagination
Il est possible de surcharger un modèle de pagination existant ou d’en définir un nouveau dans le dossier modeles
de votre squelette ou plugin. Pour cela, créez le fichier de ce nouveau modèle avec le nom désiré. Ainsi le modèle legere.html
, vous permet d’utiliser #PAGINATION{legere}
dans vos squelettes.
Les modèles de paginations reçoivent des variables d’environnement dont ils peuvent faire usage : page_courante
, nombre_pages
, bloc_ancre
. Ils peuvent aussi utiliser le filtre |bornes_pagination
qui renvoie les bornes de la pagination créée.
Pour vous faciliter la tâche, vous pouvez commencer en reprenant le code d’un modèle de pagination livré avec SPIP et l’adapter à vos besoins.
Ne pas enregistrer dans l’historique du navigateur
Il faut pour cela associer la classe CSS nohistory
au lien ajax (voir `ajax` pour les `inclure`) :
[<nav role="navigation" class="pagination">
(#PAGINATION{precedent_suivant}|replace{lien_pagination,lien_pagination nohistory})
</nav>]