Pagination 2, comme avant ... en mieux

Suite au succès de l'article Créer un système de pagination et au nombre de demandes d'amélioration, je vous propose ici une fonction pagination qui vous permettra d'afficher facilement les liens vers les autres pages.

Le principal avantage de cette fonction est qu'elle n'affiche pas les liens vers toutes les pages mais les liens vers les premières, dernières et pages adjacentes à celle en cours.
Autre avantage non négligeable, ce code fonctionnera avec des Url Rewritée sans modification de votre part.

Nous supposons que vous savez comment récupérer les données de façon à les présenter sur plusieurs pages.
Si ce n'est pas le cas, je vous invite à consulter l'article Créer un système de pagination.

La fonction pagination()

function pagination($current_page, $nb_pages, $link='?page=%d', $around=3, $firstlast=1)
{
    $pagination = '';
    $link = preg_replace('`%([^d])`', '%%$1', $link);
    if ( !preg_match('`(?<!%)%d`', $link) ) $link .= '%d';
    if ( $nb_pages > 1 ) {

        // Lien précédent
        if ( $current_page > 1 )
            $pagination .= '<a class="prevnext" href="'.sprintf($link, $current_page-1).'" title="Page précédente">&laquo; Précédent</a>';
        else
            $pagination .= '<span class="prevnext disabled">&laquo; Précédent</span>';

        // Lien(s) début
        for ( $i=1 ; $i<=$firstlast ; $i++ ) {
            $pagination .= ' ';
            $pagination .= ($current_page==$i) ? '<span class="current">'.$i.'</span>' : '<a href="'.sprintf($link, $i).'">'.$i.'</a>';
        }

        // ... après pages début ?
        if ( ($current_page-$around) > $firstlast+1 )
            $pagination .= ' &hellip;';

        // On boucle autour de la page courante
        $start = ($current_page-$around)>$firstlast ? $current_page-$around : $firstlast+1;
        $end = ($current_page+$around)<=($nb_pages-$firstlast) ? $current_page+$around : $nb_pages-$firstlast;
        for ( $i=$start ; $i<=$end ; $i++ ) {
            $pagination .= ' ';
            if ( $i==$current_page )
                $pagination .= '<span class="current">'.$i.'</span>';
            else
                $pagination .= '<a href="'.sprintf($link, $i).'">'.$i.'</a>';
        }

        // ... avant page nb_pages ?
        if ( ($current_page+$around) < $nb_pages-$firstlast )
            $pagination .= ' &hellip;';

        // Lien(s) fin
        $start = $nb_pages-$firstlast+1;
        if( $start <= $firstlast ) $start = $firstlast+1;
        for ( $i=$start ; $i<=$nb_pages ; $i++ ) {
            $pagination .= ' ';
            $pagination .= ($current_page==$i) ? '<span class="current">'.$i.'</span>' : '<a href="'.sprintf($link, $i).'">'.$i.'</a>';
        }

        // Lien suivant
        if ( $current_page < $nb_pages )
            $pagination .= ' <a class="prevnext" href="'.sprintf($link, ($current_page+1)).'" title="Page suivante">Suivant &raquo;</a>';
        else
            $pagination .= ' <span class="prevnext disabled">Suivant &raquo;</span>';
    }
    return $pagination;
}

Explications

La fonction accepte 5 paramètres (mais seuls les 2 premiers sont obligatoires).

pagination($current_page, $nb_pages, $link, $around, $firstlast);
  • $current_page - Le numéro de page actuelle
  • $nb_pages - Le nombre total de page
  • $link - Le 'href' du lien (il doit contenir %d qui sera remplacé par le numéro de page à l'aide la fonction sprintf), par défaut ?page=%d
  • $around - Le nombre de liens à afficher juste avant et juste après la page courante : par défaut 3
  • $firstlast - Le nombre de liens à afficher au début et à la fin : par défaut 1

La fonction nous retourne la liste des liens sans paragraphe, il est conseillé de l'utiliser de cette manière :

echo '<p class="pagination">' . pagination(vos_parametres) . '</p>';

Design ?

En général, c'est plus beau avec du CSS.
C'est pour ça que je vous fourni un p'tit style de base, à vous de l'adapter à votre site.

.pagination {
    line-height:2em;
}
.pagination a,
.pagination span {
    padding:0.2em 0.5em;
}
.pagination a {
    border:1px solid #9AAFE5;
    color:#105CB6;
    text-decoration:none;
}
.pagination a:hover {
    border:1px solid #296BB5;
    color:#000031;
}
.pagination .prevnext {
    font-weight:bold;
}
.pagination span.disabled { 
    border:1px solid #DDDDDD;
    color:#999999;
}
.pagination span.current {
    border:1px solid #2E6AB1;
    background-color:#2E6AB1;
    color:#ffffff;
    font-weight:bold;
}

Exemples

Des exemples d'utilisation sont disponible sur cette page.

Exemple

Intégration

Si vous désirez intégrer cette fonction avec le code présenté dans l'article Créer un système de pagination, vous devez :

  • Mettre à disposition la fonction pagination() (au début de la page ou dans un fichier externe que vous auriez inclus)
  • Utiliser pagination() pour l'affichage des liens.

Ce qui donnera :

<?php

// Numero de page (1 par défaut)
if( isset($_GET['page']) && is_numeric($_GET['page']) )
    $page = $_GET['page'];
else
    $page = 1;

// Nombre d'info par page
$pagination = 10;

// Numéro du 1er enregistrement à lire
$limit_start = ($page - 1) * $pagination;

// Préparation de la requête
$sql = "SELECT * FROM table LIMIT $limit_start, $pagination";

// Requête SQL
$resultat = mysql_query($sql);

// Traitement et affichage des données
while ( $donnee = mysql_fetch_assoc($resultat) ) {

    // ICI VOTRE CODE NORMAL
    // Affichage d'un élément

}

// Nb d'enregistrement total
$nb_total = mysql_query('SELECT COUNT(*) AS nb_total FROM table');
$nb_total = mysql_fetch_array($nb_total);
$nb_total = $nb_total['nb_total'];

// Pagination
$nb_pages = ceil($nb_total / $pagination);

// Affichage
echo '<p class="pagination">' . pagination($page, $nb_pages) . '</p>';

?>
comments powered by Disqus