The Pagination System

When a loop returns many results (dozens of articles, thousands of petition signatures), it is rarely practical, and sometimes impossible, to display everything on just one page.

Pagination allows you to distribute too many results over several pages.

SPIP therefore offers a simplified system for paginating the results of a loop.

Basic syntax

The basic version of the pagination system may be used by adding one tag and one criterion to your loops:

  • the criterion {pagination} will paginate the loop it is applied to,
  • the tag #PAGINATION, used in one of the optional parts (“before” or “after”) of this loop will display the pagination links.
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]
<BOUCLE_page(ARTICLES) {par date} {pagination}>

For a site with 90 published articles, this loop will display the ten most recent articles, and, at the top of the list, a list of links to the pages showing the 10 next elements, the 10 after that, etc. The resulting links would be similar to the following:

0 | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | ...

The index of the article slice to display will be provided in the URL with the parameter debut_page=x with the same name as the loop it refers to. This parameter can be used in other loops with the usual criterion {debut_page,10}.

Note: the total number of links displayed is limited; if you exceed the available display space, dots will be shown to go to the end of the pagination list or to come back to its beginning.

Pagination anchors

When using the #PAGINATION tag, HTML anchors are introduced which allow the browser to navigate directly to the part of the page containing the pagination.
However, if the pagination links have to be placed below the list of articles (for example), then it would be better to place this anchor at the beginning of the list.

The #ANCRE_PAGINATION tag can be used to place the anchor somewhere else. This will just return the right HTML code for the anchor and tell the #PAGINATION tag not to display its anchor.

<BOUCLE_page(ARTICLES) {par date} {pagination}>

Inversely, in order not to anchor, we will specify [(#ANCRE_PAGINATION|vide)] in the loop.

Direct access to a particular item

To allow a permanent URL to be given to a specific element of a paginated list we will use &debut_abc=@xxx where "abc" is the name of the pagination loop and "xxx" is the id of the object in the table to which the pagination relates.

Example: In a loop

[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]
<BOUCLE_pagi(ARTICLES){par titre}{pagination}>
	<li>#ID_ARTICLE : #TITRE</li>

&debut_pagi=10 places pagination on the second page (from the tenth item in the list)
&debut_pagi=@231 places pagination on the page that contains item_id "231".

The total number of results

In a loop with the {pagination} criterion, the tag
#TOTAL_BOUCLE will only display the number of elements displayed by the loop. This will then return 10 (by default) for all the pages except the last page that may contain less results.

To display the total number of elements that would have been displayed by the loop without {pagination}, you should use the #GRAND_TOTAL tag.

<BOUCLE_pagination (ARTICLES) {pagination}>
#TITRE <br />
There are #GRAND_TOTAL articles, this page only displays #TOTAL_BOUCLE articles at a time.

will display: “There are 15570 articles, this page only displays 10 articles at a time.”

Changing the {pagination} “step”

The default number of elements returned by a paginated loop is 10. This can easily be modified by adding a parameter to the criterion.

For example,

<BOUCLE_page (ARTICLES) {pagination 5}>
#TITRE <br />

will display the titles of the 5 articles stating from the article corresponding to the current value of the debut_page environment variable.

The value of the parameter can be a constant or any tag — in particular #ENV{xx} — which give the opportunity to do a fully on-request display.

Pagination and inclusions

If the pagination is in an included loop, you must add the parameter ajax , env to the INCLURE tag. This is required for the included template to be able to compute the parameter debut_xxx, and is also justified for safety reasons (the #PAGINATION tag is actually calculated based on the complete URL of the page).

Naming the pagination criteria

When using templates that are included several times in the same page, such as:

<BOUCLE_incluse(ARTICLES){id_rubrique}{par titre}>

and that this INCLURE has a pagination implemented (which is why we use the {env} criterion), whenever you click on a pagination, you will see all of the paginations modified at the same time.

<BOUCLE_groupe5(MOTS){id_groupe=5}{pagination 15 #ID_ARTICLE}>
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]

To avoid this happening, you will need to simply name the pagination criterion inside the included file with a name that will be different for each inclusion:

You may also want to specify the name you want to give to the pagination criterion when you call INCLURE:

<INCLURE{fond=page_paginee, env, nom_p=_abc}>
<INCLURE{fond=page_paginee, env, nom_p=_def}>

in page_paginee.html :

<BOUCLE_a(ARTICLES){pagination 25 #ENV{nom_p}}>
[<nav role="navigation" class="pagination">(#PAGINATION)</nav>]

Styling the pagination

The list of pages constructed by the #PAGINATION contains a series of links with the current page having the class “.on”. You can therefore style this list by changing the styles of the <tt>a</tt> and <tt>.on</tt> selector.

Selecting the pagination model

The #PAGINATION tag can accept a parameter for the {modele}, which allows you to modify the displayed results of the tag.

This is how #PAGINATION{precedent_suivant} will display the links to the previous and following pages. The links will look like this:

previous page | next page

#PAGINATION{page} will display something that looks like this:

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ...

#PAGINATION{page_precedent_suivant} will display something like this:

previous page 1 | 2 | 3 | 4 | 5 | 6 | next page

#PAGINATION{prive} will display something like this:

0 | 10 | 20 | 30 | Display all

It is possible to define other pagination models, which need to be named pagination_modelname. When building your own, it might be helpful to inspire yourself from those that are delivered with the standard SPIP distribution located in the prive/modeles/ directory.

Customise the pagination template

Each model has parameters that can be customised.
For example, #PAGINATION{page_precedent_suivant} displays by default:

page précédente 1 | 2 | 3 | 4 | 5 | 6 | page suivante

#PAGINATION{page_precedent_suivant, label_precedent=&lt;, label_suivant=&gt;} affiche :

< 1 | 2 | 3 | 4 | 5 | 6 | >

Setting up the address of the #PAGINATION links

From SPIP 3.2.8 onwards, it is possible to specify which URL should be used as the basis for links generated by the #PAGINATION tag.

For example, this allows you to clean up an unwanted URL variable if necessary:

Setting up the number of links

Since SPIP 4.0, the various pagination templates accept a nombre_liens_max parameter which, passed to the #PAGINATION tag, allows the maximum number of pagination links displayed by the template to be defined. One can also use the constant _PAGINATION_NOMBRE_LIENS_MAX.

Defining a new pagination model

It is possible to override an existing pagination template or define a new one in the modeles directory of your template or plugin. To do this, create the file for this new template with the desired name. So the template light.html, allows you to use #PAGINATION{light} in your templates.

Pagination templates are given environment variables which they can make use of: page_courante, nombre_pages, bloc_ancre. They can also use the |bornes_pagination filter which returns the bounds of the pagination created.
To make things easier, you can start by taking the code from a pagination template that comes with SPIP and adapting it to your needs.

Author jack, mortimer Published : Updated : 18/04/23

Translations : català, English, Español, français, italiano, Nederlands