Paginator Released

Posted 2006-10-24…

Writing paginators sucks, and it’s something that we get stuck with doing from time to time. Deceptively simple, they can be pretty tedious to write— and they’re definitely not the type of code that makes you go, “Wow, that’s just cool!” I mean, comeon… this isn’t rocket science, it’s just boring.

The problem with most paginators (ie, the paginator in Rails) is that they’re tightly coupled with what they’re paginating— so it’s difficult to just rip them out and use the code elsewhere. On top of that, many times they’re too rigid (hard to change pages) or make it difficult to query for metadata (is this the last page?).

For a while now I’ve been using a “custom” paginator in my Rails projects; a small library I wrote so that I would have more control over changing pages and seeing metadata. From the beginning this paginator was written to be framework agnostic— something I can just rip out and use elsewhere (ie, a CLI, etc)— for one simple reason. I never want to have to write another paginator again.

Today I released the paginator 1.0.0, available as a gem. Here’s a quick example:

Rails

In your controller

PER_PAGE = 20
@pager = Paginator.new(Foo.count, PER_PAGE) do |offset, per_page|
Foo.find(:all, :limit => per_page, :offset => offset)
end
@page = @pager.page(params[:page])

In your view

<% @page.each do |foo| >
<
# Show something for each item >
<
end >
<
= @page.number >
<
= link_to(“Prev”, foos_url(:page => @page.prev.number)) if @page.prev? >
<
= link_to(“Next”, foos_url(:page => @page.next.number)) if @page.next? %>

Elsewhere

bunch_o_data = (1..60).to_a
PER_PAGE = 10
pager = Paginator.new(bunch_o_data.size, PER_PAGE) do |offset, per_page|
bunch_o_data[offset,per_page]
end
pager.each do |page|
puts “Page ##{page.number}”
page.each do |item|
puts item
end
end

It’s pretty simple stuff. You instantiate a Paginator object, telling it how many records there are and how many you’d like per page. You also pass a block that will be used to return the records for a page, given the record offset (and the number of records per page— which you just passed into the constructor— as a convenience).

To get it, it’s simple:

sudo gem install paginator

The full docs are here.