How to install pagy gem with a custom pagination template on a Ruby on Rails application
This minipost will guide you through all the required steps in order to successfully install pagy gem for pagination on a Ruby on Rails application using a custom HTML template.
Pagy gem installation steps
Start by adding the pagy gem to your application Gemfile [appname/Gemfile] by:
gem 'pagy', '~> 3.0.0'
Go to the application directory [appname]:
cd appname
and perform bundle install
inside directory to install the pagy gem:
bundle install
Before you start developing the pagination view, you need to include
two separate pagy modules, they are called: Pagy::Backend
and Pagy::Frontend
in different parts of your application.
Include Pagy::Backend
module to your application_controller.rb
or only in a specific controller depending on where you will use pagination. If you have multiple controllers offering pagination, a good place to include
this is the controller that all the other controllers inherit from(i.e. ApplicationController
[appname/app/controllers/application_controller.rb])
We are going to include the module in ApplicationController
[appname/app/controllers/application_controller.rb]:
# Application controller class ApplicationController < ActionController::Base # Pagy include Pagy::Backend end
Now, it's time to include the Pagy::Frontend
module. We will include
it in ApplicationHelper
[app/helpers/application_helper.rb]:
module ApplicationHelper # Pagy include Pagy::Frontend end
Having both the include
-s in place, we need to add the relevant Rails partial with the pagination HTML code.
Important here to notice is that by using the default pagination integrations of pagy with bootstrap or other frameworks, you achieve even faster results in speed. However, when the project you are working on has custom HTML pagination, the easiest way is to use a rails partial to customize the pagination implementation.
Pagy offers HTML templates to start customization. Navigate to pagy haml pagination template and copy the template content, create a partial _pagination.html.haml
[app/views/shared/_pagination.html.haml] and paste the following template:
-# This template is i18n-ready: if you don't use i18n, then you can replace the pagy_t -# calls with the actual strings ("‹ Prev", "Next ›", "…"). -# The link variable is set to a proc that returns the link tag. -# Usage: link.call( page_number [, text [, extra_attributes_string ]]) - link = pagy_link_proc(pagy) %nav.pagy_nav.pagination{"aria-label" => "pager", :role => "navigation"} - if pagy.prev %span.page.prev!= link.call(pagy.prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"') - else %span.page.prev.disabled!= pagy_t('pagy.nav.prev') - pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] - if item.is_a?(Integer) # page link %span.page != link.call(item) - elsif item.is_a?(String) # current page %span.page.current= item - elsif item == :gap # page gap %span.page.gap!= pagy_t('pagy.nav.gap') - if pagy.next %span.page.next!= link.call(pagy.next, pagy_t('pagy.nav.next'), 'aria-label="next"') - else %span.page.next.disabled!= pagy_t('pagy.nav.next')
You can now start editing the template and alter the HTML provided with your own custom HTML markup. If you are not using HAML, there is the pagy html erb pagination template and there is also the pagy slim pagination template to start the implementation.
Choose the preferred one and edit the HTML code with your own custom markup.
Let's assume that you are willing to paginate a posts controller index action where all the posts are being displayed. Jump to the controller you are willing to implement pagination and add the following pagy line:
class PostsController < ApplicationController def index @pagy, @posts = pagy(Post.all.order(created_at: :desc)) end end
You are free to choose any selection and ordering, for simplicity, I have used Post.all.order(created_at: :desc)
. Alter the collection inside the brackets with your preferred collection for pagination.
Having the @pagy
variable on your controller action, you are now ready to add the pagination layout to the relevant view.
Navigate to [app/views/posts/index.html.haml] or in your relevant view for the above controller setup and add the following render partial
in the place you want to yield the pagination template:
= render partial: 'shared/pagination', locals: { pagy: @pagy }
Refresh your application, and there you go, you now have your pagination component rendered.
Two more, things before you go.
The pagy.rb
initializer
You can use the pagy.rb
initializer that comes with many options to customize the implementation. For this minipost, I will use only the default pagination items per page. All other options have been omitted for brevity(more options at pagy.rb initializer). Copy the following content to your pagy.rb
[appname/app/config/initializers/pagy.rb] initializer
[..] # Instance variables # See https://ddnexus.github.io/pagy/api/pagy#instance-variables Pagy::VARS[:items] = 10 [..]
In the above initializer, we have set the default pagination items per page to 10 items across all pagy implementations inside the application.
Alternatively, you can set directly in the pagy
controller call the items per page that you want to get paginated in your view, overriding the general setting of the pagy.rb
initializer, by:
@pagy, @posts = pagy(Post.all.order(created_at: :desc), items: 20)
The above will paginate 20 items per page.
Pagy i18n
localization
Pagy also offers i18n localization and by default supports the following locales: en
, es
, fr
and a couple more.
If your locale is not on the list, you can copy the en
localization file from pagy en locale file and add your custom locales. For the above _pagination.html.haml
I have used only the following 3 locale variables for the el
locale [config/locales/pagy.el.yml].
el: pagy: nav: prev: "‹ Προηγούμενη" next: "Επόμενη ›" gap: "…"
Additional information:
![Buy Me A Coffee](https://www.aloucaslabs.com/assets/buy_me_a_coffee_yellow-f445e8acabfc1759d6c0143283b7769ba571d309238b6d2f772baeb857a21eb0.png)