Rendering will_paginate links nicely with Twitter Bootstrap

When I was working with Moviemates (my one dream pet project), I had to use will_paginate gem for pagination of the movie listings. As the UI are based on Twitter Bootstrap, the will_paginate links (generated by its view helpers) were looking very ugly. Please check the following screenshot to see how bad it was looking!

I had to google a while for a decent look of these links. I’ve found a very effective but easy fix written by  oparrish and shared here. For your conveniences, the gist is attached here:

module BootstrapPaginationHelper
	class LinkRenderer < WillPaginate::ActionView::LinkRenderer
		protected

      def page_number(page)
        unless page == current_page
          link(page, page, :rel => rel_value(page))
        else
          link(page, "#", :class => 'active')
        end
      end

      def gap
        text = @template.will_paginate_translate(:page_gap) { '&hellip;' }
        %(<li class="disabled"><a>#{text}</a></li>)
      end

      def next_page
        num = @collection.current_page < @collection.total_pages && @collection.current_page + 1
        previous_or_next_page(num, @options[:next_label], 'next')
      end

      def previous_or_next_page(page, text, classname)
        if page
          link(text, page, :class => classname)
        else
          link(text, "#", :class => classname + ' disabled')
        end
      end

      def html_container(html)
        tag(:div, tag(:ul, html), container_attributes)
      end

    private

    	def link(text, target, attributes = {})
        if target.is_a? Fixnum
          attributes[:rel] = rel_value(target)
          target = url(target)
        end

				unless target == "#"
					attributes[:href] = target
				end

        classname = attributes[:class]
        attributes.delete(:classname)
        tag(:li, tag(:a, text, attributes), :class => classname)
    	end
	end
end

When you embed the will_paginate in the view, you just need to pass this helper and the links will be rendered using this helper.

    = will_paginate(@movies, :renderer => 'BootstrapPaginationHelper::LinkRenderer')

However, as i needed some more customizations on every pagination links in my application, I’ve written another helper method (in my application helper) with all my required customizations.

 def pagination_links(collection, options = {})
    options[:renderer] ||= BootstrapPaginationHelper::LinkRenderer
    options[:class] ||= 'pagination pagination-centered'
    options[:inner_window] ||= 2
    options[:outer_window] ||= 1
    will_paginate(collection, options)
  end

In my views, I just needed to call this helper method instead of default method to render page links:

= pagination_links(@movies)

Now, see, how nice it looks:

However, today i’ve seen (but not tested) a easier solution. There is a separate gem released for the same purpose. It is named will_paginate_bootstrap. I think you can use that if you want. Usage detail are available on their site.

  • Excellent article!, i was about to need the same thing.

  • Estanislao Vizcarra

    Thanks a lot, this help me 😀

  • Sundara Suganya S

    Really it helps me to solve issue in my project,thanks a lot ..