will_paginate with Bootstrap

2019 Jan 29

will_paginate doesn’t come with Bootstrap style pagination by default. However, as its doc says, it does support customization by providing your own LinkRenderer.

to customize HTML output of will_paginate, you’ll need to subclass WillPaginate::ActionView::LinkRenderer

Below is a simple implementation to render pagination links with Bootstrap(4) css components.

# app/helpers/application_helper.rb

module ApplicationHelper
  def will_paginate(collection_or_options = nil, options = {})
    if collection_or_options.is_a? Hash
      options, collection_or_options = collection_or_options, nil
    end
    unless options[:renderer]
      options = options.merge :renderer => BootstrapRenderer
    end
    super *[collection_or_options, options].compact
  end

  class BootstrapRenderer < WillPaginate::ActionView::LinkRenderer
    protected
    def html_container(html)
      tag :nav, tag(:ul, html, class: "pagination pagination-sm"), container_attributes
    end

    def page_number(page)
      tag :li, link(page, page, rel: rel_value(page), class: 'page-link'),
        class: (page == current_page ? 'page-item active': 'page-item')
    end

    def previous_or_next_page(page, text, classname)
      tag :li, link(text, page || '#', class: 'page-link'),
        class: ['page-item', classname, ('disabled' unless page)].join(' ')
    end
  end
end
# app/views/posts/index.html.erb

# use 'text-center' to center inline-blocks (<ul>) within <nav>
<%= will_paginate @posts, params: @will_paginate_params, class: 'text-center' %>