Pagination Tutorial

Difficulty: Medium

Hi my name is Tom, a web developer from the UK. Dlib was looking for contributions to the blog so here I am.

The Pagination library is always met with some confusion; many people think that it perhaps acts as a wrapper around the database library, or that it has complex functionality. The happy truth is that pagination is actually simple to use - and amazingly useful. So I’m here to set the record straight.

Pagination is simply about creating the links to multiple sub-pages; it does not handle your data at all! You tell the library how many lines of data you have (say from a database) and how many lines you will be showing per page, then it works out the links for you (providing you with some options to set the style etc.). It is up to you to work out which page your on, select the appropriate data and present it on the page.

Simple Example
The best way to learn is by a simple example. Lets create set of a pagination links for some made up data. The pagination class has several options to customise it’s behaviour. First we’ll look at the main ones (that you need to change) and later I’ll deal with the optional parameters.

The pagination lib is loaded the same way as any other Kohana library.

$this->pagination = new Pagination();

The 3 main things you need to pass to the library are: ‘uri_segment’, ‘total_items’, ‘items_per_page’.

  • uri_segment: the segment of your url after which to put the page # (eg: passing “items” with the url page/items makes links such as page/items/2)
  • total_items: the total # of items you have to display (eg here you might use an sql query: $myquery->num_rows() )
  • items_per_page: this sets the items you intend to display per page

Lets check out a simple example:

class Example_Controller extends Controller {
 
    public function items()
    {
        // first start and configure the P class
        $this->pagination = new Pagination(array(
                                                 'uri_segment'=>"items",
                                                'total_items'=>50,
                                                'items_per_page'=>10));
        // pagination works out that you would have 5 pages (10 items per page)
        // we use create_links to return the links html
        echo $this->pagination->create_links();
        // here you would get your relevant 10 items
        // and display them!
    }
}

See nice and simple! Save this as Example.php in your controllers folder and load it up. You should see something similar to the image below:

Example of the classic stlye pagination

Customisation
As exciting as our example is it isn’t very exciting to look at; this is the classic stlye links (the default used by the library). Luckily there are a few alternative display styles: digg, extended and punbb (you can see examples of them further down the page).

You can set the style either by passing it as an option when you initialise the library (”style”=>”digg” for example) or as a parameter to create links (eg: $pagination->create_links(”punbb”);).

Another configuration option is “base_url” which allows you to set the url that pagination links point to.

This extended example class shows all of the various options available. Save it in your controllers folder and check the output.

class Example_Controller extends Controller {
 
    public function items()
    {
        // first start and configure the P class
        $this->pagination = new Pagination(array(
                                                 'base_url'=>"page/items",
                                                 'uri_segment'=>"items",
                                                 'style'=>"classic",
                                                 'total_items'=>50,
                                                 'items_per_page'=>10));
        // pagination works out that you would have 5 pages (10 items per page)
        // normal (classic style) links
        echo $this->pagination->create_links();
 
        // digg links
        echo $this->pagination->create_links("digg");
 
        // punbb links
        echo $this->pagination->create_links("punbb");
 
        // extended links
        echo $this->pagination->create_links("extended");
    }
}

The output should be similar to this (taken from the Kohana wiki):

All the pagination example styles (from the Kohana wiki)

Class properties

I mentioned before that the Pagination library did not do any data handling. Whilst this is true it does have some basic options for working out what data you need to select for the page.

The class properties of interest are:

  • current_page
  • total_pages
  • current_first_item
  • current_last_item
  • first_page
  • last_page
  • previous_page
  • next_page
  • sql_offset
  • sql_limit

The sql_limit and sql_offset provide the offset/limit required in an SQL query to select the right rows for the current page. The other options should be fairly obvious too.

Complex example
Lets finish off with a complex example that actually shows some data. Lets assume we have a table (”my_items”) with a single column (item_num) in our database with 100 rows of data. We are going to grab the data, display it on the page and have digg stlye pagination links at the top.

Save this as Example.php and give it a go!

class Example_Controller extends Controller {
 
    public function __construct()
    {
        $this->db = new Database;
    }
    public function items()
    {
        // we need to work out the number of total rows first
        $query = $this->db->from("my_items")->get();
        // start and configure the P class
        $this->pagination = new Pagination(array(
                                                 'uri_segment'=>"items",
                                                 'style'=>"digg",
                                                 'total_items'=>$query->num_rows(),
                                                 'items_per_page'=>10));
 
       // echo the digg style links
        echo $this->pagination->create_links();
 
        // now we need another query to retrieve the right data
        $query = $this->db->from("my_items",)->limit($this->pagination->sql_limit)->offset($this->pagination->sql_offset)->get();
 
        // finally echo the data
        foreach($query as $row)
        {
            echo $row->item_num.'<'.'br />';
        }
 
    }

As you can see pagination is a simple and powerful library! I hope this quick and dirty guide was of use :)


11 Responses to “Pagination Tutorial”

  1. bennythemink Says:

    Nice tutorial Errant, thanks for that!

  2. jalex Says:

    Thanks for tutorial!
    What if you are trying to work with ORM? How would you do it?

  3. Errant Says:

    Uh well remember an ORM instance (at least in Kohana) theoretically just refers to one row in the database :)

    To paginate the many rows of a one-to-many relationship you’d have to hack at the core slightly to be able to run get_related_ with a limit/offset parameter.

    I’ll try and post a tutorial covering that when I finally get un-busy :P

    @Dlib: thanks for publishing this ;) I forgot (and then got super busy!!) be back sooooon :D

  4. Errant Says:

    uh by “hack the core” I mean “hack the ORM model” ;)

  5. dlib Says:

    I wasn’t sure whether it was done or not but figured it was finished since it looked fairly complete :) Anyway, thanks for the tutorial.

  6. Trainwreck Says:

    Posted one day before I needed this… your timing is perfect :) Thanks for this!

  7. Mike Says:

    Does the last example work? I don’t think so.

  8. Errant Says:

    Your right. $query->num_rows() should be $query->count(). (that, incidentally, is one of the few things I dislike about Kohana’s db library.. it always gets me :))

  9. Mike Says:

    Still doesn’t work: “Cannot redeclare class Example_Controller”

  10. Errant Says:

    Well where are you saving this?

    It works for me using a default Kohana App and saving this in controllers/example.php
    :)

    Try changing the name to Demo_Controller and saving in controllers/demo.php

  11. Mike Says:

    Sorry, no luck. I did changed to Demo…

    http://localhost/p/index.php/demo/items

    The same error: Fatal error: Cannot redeclare class Demo_Controller in C:\xampplite\htdocs\p\application\controllers\demo.php on line 32

    db = new Database;
    }
    public function items()
    {
    // we need to work out the number of total rows first
    $query = $this->db->from(”notes”)->get();
    // start and configure the P class
    $this->pagination = new Pagination(array( ‘uri_segment’=>”items”,
    ’style’=>”digg”,
    ‘total_items’=>$query->count(),
    ‘items_per_page’=>10));
    // echo the digg style links
    echo $this->pagination->create_links();

    // now we need another query to retrieve the right data
    $query = $this->db->from(”notes”)->limit($this->pagination->sql_limit)->offset($this->pagination->sql_offset)->get();

    // finally echo the data
    foreach($query as $row)
    {
    echo $row->id.”;
    }

    }
    }
    ?>

Leave a Comment