Tutorial: PHP Pagination with Ellipses

Assume you’re developing a web site that requires pagination, and the quantity of pages makes it ugly and impractical to show every single page in the navigation toolbar. What you need is a navigation list where the far edges from the current page are cut off and replaced with dots or ellipses (“…”). Here is a simple PHP code that generates just that.

What we will create:

When the current page is in the middle of the navigation

When the current page is at the end of the navigation

There are several ways to split up pages using ellipses. This example will make two ellipses on each end, except when we’re at a page that is near the first or final pages – in which case we only get one ellipsis at the opposite end. There will always be page links to the very first and the very last page. Try the demo below to see how the pagination works:

[line][demobutton align=”center” href=”http://cappelendesign.no/wp-content/uploads/code/ellipses-pagination/index.php”][line]

This tutorial assumes you already know how to retrieve a limited portion of the data to display on each page. For example you’d use MySQL’s LIMIT or OFFSET mechanisms if the data is retrieved from a database.

The pagination code is made generic by placing it inside a PHP function and allowing parameters to control the output. What we need to know before we call the pagination function is:

  • Current page. Usually fetched from the URL, e.g. $_GET['page'].
  • The number of pages in total. This number can easily be found by dividing the total number of entries by how many we want per page. E.g. ceil($total_number_of_entries / $number_per_page)).

I’ve also added parameters for the base URL the pagination links should have, and whether or not we want to show ‘Previous’ and ‘Next’ links at the very ends (false as default). Here’s the function:

function insertPagination($base_url, $cur_page, $number_of_pages, $prev_next=false) {
     $ends_count = 1;  //how many items at the ends (before and after [...])
     $middle_count = 2;  //how many items before and after current page
     $dots = false;
     <ul class="pagination">
     if ($prev_next && $cur_page && 1 < $cur_page) {  //print previous button?
          ?><li class="prev"><a href="<?php echo $base_url; ?>?page=<?php echo $cur_page-1; ?>">&laquo; Previous</a></li><?php
     for ($i = 1; $i <= $number_of_pages; $i++) {
          if ($i == $cur_page) {
               ?><li class="active"><a><?php echo $i; ?></a></li><?php
               $dots = true;
          } else {
               if ($i <= $ends_count || ($cur_page && $i >= $cur_page - $middle_count && $i <= $cur_page + $middle_count) || $i > $number_of_pages - $ends_count) { 
                    ?><li><a href="<?php echo $base_url; ?>?page=<?php echo $i; ?>"><?php echo $i; ?></a></li><?php
                    $dots = true;
               } elseif ($dots) {
                    $dots = false;
     if ($prev_next && $cur_page && ($cur_page < $number_of_pages || -1 == $number_of_pages)) { //print next button?
          ?><li class="next"><a href="<?php echo $base_url; ?>?page=<?php echo $cur_page+1; ?>">Next &raquo;</a></li><?php

Function call example:

insertPagination('index.php', $current_page, $number_of_pages, true);

Whereas we send the current page as $current_page, the calculated number of pages as $number_of_pages, and true to get ‘Previous’ and ‘Next’ links.

If you’re familiar with PHP you could make this function even more generic by adding parameters to define how many page links to show before/after current page ($middle_count) and how many at the ends ($ends_count). You can also allow function calls to decide the labels on the ‘Previous’ and ‘Next’ links.

Hope this was useful!