Pagination with Pagy & Bootstrap

For a recent project, I needed an easy, ready-to-go pagination plugin for a Rails application. In the past, I’d used will_paginate and Kaminari. (Kami means paper, but Kaminari may or may not translate to “Thunder.” Someone fill me in.) When I went to check on the health of the project, I saw that will_paginate was in a maintenance-only state and that Kaminari hadn’t seen an update in over a year. Rails is far from dead yet, so I went searching for an alternative and found Pagy.

I was skeptical of the performance claims made in the readme, but it sure looked promising, so I decided to give this gem a go. I decided I wanted to live on the edge, so I went ahead and added the latest version to my gemfile.

gem 'pagy' 

Pagy ended up at version ‘4.11.0’ at the time of this writing. After adding Pagy to your gemfile, run:

bundle update && bundle install

One of the more interesting things about Pagy, is that you need to add a configuration file to your application. Since I’m on Rails, I located it in config/initializers. You can find the file here. I simply grabbed the file with wget.

cd config/initializers/

wget https://raw.githubusercontent.com/ddnexus/pagy/master/lib/config/pagy.rb

Next, you’ll need to include the Pagy backend. I went ahead and used my ApplicationController, since I plan to use this almost everywhere. In controllers/application_controller.rb, modify it to include the following:

class ApplicationController < ActionController::Base
  include Pagy::Backend
end

We need to add the pagy method to a controller action. If you’ve just scaffolded a controller, you’ll find a suitable use case in the index method. It probably looks like this:

def index
    @widgets = Widget.all
End

What we are going to do, is refactor it. This is just an example, so we’re going to grab all the widgets at once for simplicity.

def index
  @pagy_widgets, @widgets = pagy(Widget.all)
End

Now, for rendering your pagination you have two options. You can do it the frontend JavaScript or server side way. In my case, this is an in-office back-end application. I’m going for reliability and maintainability, and not trying to build a single page app. In my case I’m going to render everything server side.

First step, we must include the frontend someplace, such as a helper:

include Pagy::Frontend

Next, we add the links to our view. Pagy will figure our that @pagy_widgets paginates a bunch of @widgets in a for_each. (It’s magic!)

!= pagy_nav(@pagy_widgets)

Because I am using HAML (which is like SLIM) you will see that I need to add a bang first. This will render your links.

Now, these links are pretty ugly. We are going to make them integrate better with Bootstrap. Uncomment require ‘pagy/extras/bootstrap’ in the pagy.rb initializer we downloaded earlier.

# Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination
# See https://ddnexus.github.io/pagy/extras/bootstrap
# require 'pagy/extras/bootstrap'

You’ll see more frontend extras for Foundation, Materialize, and Bulma.

 != pagy_bootstrap_nav(@pagy)

Don’t forget, you’ll need to restart your Rails development server or you’ll get an error – the changes haven’t been initialized yet.


Leave a Reply

Your email address will not be published. Required fields are marked *