├── .gitignore ├── Gemfile ├── MIT-LICENSE ├── README.markdown ├── Rakefile ├── example └── app.rb ├── lib ├── bootstrap_pagination │ ├── action_view.rb │ ├── bootstrap_renderer.rb │ ├── sinatra.rb │ └── version.rb ├── will_paginate-bootstrap.rb └── will_paginate │ └── bootstrap.rb ├── pagination.png ├── spec └── pagination_spec.rb └── will_paginate-bootstrap.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | .idea/ 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in will_paginate-bootstrap.gemspec 4 | gemspec 5 | 6 | group :development do 7 | gem "rake" 8 | gem "nokogiri" 9 | gem "minitest" 10 | end 11 | 12 | group :example_app do 13 | gem "sinatra" 14 | end -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Nicholas Dainty 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # will_paginate-bootstrap 2 | 3 | --- 4 | 5 | __No longer maintained__ 6 | 7 | I'm no longer using Bootstrap with Rails, so unfortunately am no longer accepting pull requests or maintaining this library. Feel free to fork this repository in order to publish your changes, or get in touch with me if you'd like to take over maintenance of the gem. 8 | 9 | --- 10 | 11 | [![Code Climate](https://codeclimate.com/github/bootstrap-ruby/will_paginate-bootstrap.png)](https://codeclimate.com/github/bootstrap-ruby/will_paginate-bootstrap) 12 | 13 | ![Bootstrap Pagination Component](https://raw.github.com/bootstrap-ruby/will_paginate-bootstrap/master/pagination.png) 14 | 15 | This gem integrates the [Twitter Bootstrap](http://getbootstrap.com/) [pagination component](http://getbootstrap.com/components/#pagination) with the [will_paginate](https://github.com/mislav/will_paginate) pagination gem. 16 | 17 | Just like will_paginate, Rails and Sinatra are supported. 18 | 19 | ## Install 20 | 21 | * `gem install will_paginate-bootstrap`, *or* 22 | * For projects using Bundler, add `gem 'will_paginate-bootstrap'` to your `Gemfile` (and then run `bundle install`). 23 | 24 | ## Usage 25 | 26 | ### Rails 27 | 28 | 1. Load the Bootstrap CSS in your template. 29 | 2. In your view, use the `renderer: BootstrapPagination::Rails` option with the `will_paginate` helper, for example: 30 | 31 | ```ruby 32 | <%= will_paginate @collection, renderer: BootstrapPagination::Rails %> 33 | ``` 34 | 35 | ### Sinatra 36 | 37 | 1. Load the Bootstrap CSS in your template. 38 | 2. `require "will_paginate-bootstrap"` in your Sinatra app. 39 | 3. In your view, use the `renderer: BootstrapPagination::Sinatra` option with the `will_paginate` helper, for example: 40 | 41 | ```ruby 42 | <%= will_paginate @collection, renderer: BootstrapPagination::Sinatra %> 43 | ``` 44 | 45 | ## Compatibility 46 | 47 | Starting at version 1.0, this gem no longer supports Bootstrap 2. 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
Ruby>= 1.9.2
will_paginate>= 3.0.3
Twitter Bootstrap>= 3.0.0
63 | 64 | Bootstrap 2 users can use version `0.2.5` of the gem which was the last version to offer Bootstrap 2 support. 65 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rake/testtask" 3 | 4 | Rake::TestTask.new do |t| 5 | t.pattern = "spec/*_spec.rb" 6 | end 7 | 8 | task :default => :test -------------------------------------------------------------------------------- /example/app.rb: -------------------------------------------------------------------------------- 1 | require "sinatra" 2 | require "will_paginate-bootstrap" 3 | require "will_paginate/collection" 4 | 5 | CDN_PATH = "//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" 6 | 7 | $template = < 9 | 10 | will_paginate-boostrap Example App 11 | 12 | 13 | 14 | <%= will_paginate @collection, renderer: BootstrapPagination::Sinatra %> 15 | 16 | 17 | EOHTML 18 | 19 | def build_collection 20 | page = if params[:page].to_i > 0 21 | params[:page].to_i 22 | else 23 | 1 24 | end 25 | 26 | @collection = WillPaginate::Collection.new page, 10, 100000 27 | end 28 | 29 | get "/" do 30 | build_collection 31 | erb $template 32 | end 33 | -------------------------------------------------------------------------------- /lib/bootstrap_pagination/action_view.rb: -------------------------------------------------------------------------------- 1 | require "will_paginate/view_helpers/action_view" 2 | require "bootstrap_pagination/bootstrap_renderer" 3 | 4 | module BootstrapPagination 5 | # A custom renderer class for WillPaginate that produces markup suitable for use with Twitter Bootstrap. 6 | class Rails < WillPaginate::ActionView::LinkRenderer 7 | include BootstrapPagination::BootstrapRenderer 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/bootstrap_pagination/bootstrap_renderer.rb: -------------------------------------------------------------------------------- 1 | require "bootstrap_pagination/version" 2 | 3 | module BootstrapPagination 4 | # Contains functionality shared by all renderer classes. 5 | module BootstrapRenderer 6 | ELLIPSIS = "…" 7 | 8 | def to_html 9 | list_items = pagination.map do |item| 10 | case item 11 | when Fixnum 12 | page_number(item) 13 | else 14 | send(item) 15 | end 16 | end.join(@options[:link_separator]) 17 | 18 | tag("ul", list_items, class: ul_class) 19 | end 20 | 21 | def container_attributes 22 | super.except(*[:link_options]) 23 | end 24 | 25 | protected 26 | 27 | def page_number(page) 28 | link_options = @options[:link_options] || {} 29 | 30 | if page == current_page 31 | tag("li", tag("span", page), class: "active") 32 | else 33 | tag("li", link(page, page, link_options.merge(rel: rel_value(page)))) 34 | end 35 | end 36 | 37 | def previous_or_next_page(page, text, classname) 38 | link_options = @options[:link_options] || {} 39 | 40 | if page 41 | tag("li", link(text, page, link_options), class: classname) 42 | else 43 | tag("li", tag("span", text), class: "%s disabled" % classname) 44 | end 45 | end 46 | 47 | def gap 48 | tag("li", tag("span", ELLIPSIS), class: "disabled") 49 | end 50 | 51 | def previous_page 52 | num = @collection.current_page > 1 && @collection.current_page - 1 53 | previous_or_next_page(num, @options[:previous_label], "prev") 54 | end 55 | 56 | def next_page 57 | num = @collection.current_page < @collection.total_pages && @collection.current_page + 1 58 | previous_or_next_page(num, @options[:next_label], "next") 59 | end 60 | 61 | def ul_class 62 | ["pagination", @options[:class]].compact.join(" ") 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /lib/bootstrap_pagination/sinatra.rb: -------------------------------------------------------------------------------- 1 | require "will_paginate/view_helpers/sinatra" 2 | require "bootstrap_pagination/bootstrap_renderer" 3 | 4 | module BootstrapPagination 5 | # A custom renderer class for WillPaginate that produces markup suitable for use with Twitter Bootstrap. 6 | class Sinatra < WillPaginate::Sinatra::LinkRenderer 7 | include BootstrapRenderer 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/bootstrap_pagination/version.rb: -------------------------------------------------------------------------------- 1 | module BootstrapPagination 2 | VERSION = "1.0.1" 3 | end 4 | -------------------------------------------------------------------------------- /lib/will_paginate-bootstrap.rb: -------------------------------------------------------------------------------- 1 | require "will_paginate/bootstrap" -------------------------------------------------------------------------------- /lib/will_paginate/bootstrap.rb: -------------------------------------------------------------------------------- 1 | require 'will_paginate' 2 | 3 | if defined?(ActionView) 4 | require "bootstrap_pagination/action_view" 5 | end 6 | 7 | if defined?(Sinatra) 8 | require "bootstrap_pagination/sinatra" 9 | end 10 | -------------------------------------------------------------------------------- /pagination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bootstrap-ruby/will_paginate-bootstrap/1a0d7b3af5a314f9046714c6356a750d0a6197e2/pagination.png -------------------------------------------------------------------------------- /spec/pagination_spec.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'nokogiri' 3 | require 'will_paginate/array' 4 | require 'will_paginate/view_helpers/link_renderer' 5 | require 'bootstrap_pagination/bootstrap_renderer' 6 | 7 | include WillPaginate::ViewHelpers 8 | 9 | # Renderer class that's not tied to any web framework. 10 | class MockRenderer < WillPaginate::ViewHelpers::LinkRenderer 11 | include BootstrapPagination::BootstrapRenderer 12 | 13 | HASH = '#' 14 | 15 | def url(args) 16 | HASH 17 | end 18 | end 19 | 20 | describe "Bootstrap Renderer" do 21 | # Render pagination for the middle page so that we can test for the presence of 22 | # start, prev and next links. We should also be able to test for test for the 23 | # presence of a "gap" item if the collection size is large enough. 24 | let(:collection_size) { 15 } 25 | let(:page) { (collection_size / 2.0).to_i } 26 | let(:collection) { 1.upto(collection_size).to_a } 27 | let(:link_options) { nil } 28 | let(:class_opt) { nil } 29 | 30 | let(:output) do 31 | will_paginate( 32 | collection.paginate(:page => page, :per_page => 1), 33 | renderer: MockRenderer, link_options: link_options, 34 | class: class_opt 35 | ) 36 | end 37 | 38 | let(:html) { Nokogiri::HTML.fragment(output) } 39 | 40 | it "returns a string" do 41 | output.must_be_kind_of String 42 | end 43 | 44 | it "returns a string containing HTML" do 45 | html.must_be_kind_of Nokogiri::HTML::DocumentFragment 46 | end 47 | 48 | it "has an active list item" do 49 | html.at_css('ul li.active').wont_be_nil 50 | end 51 | 52 | it "has a gap item with class disabled" do 53 | html.at_css('ul li.disabled').wont_be_nil 54 | end 55 | 56 | it "has one item with rel start value" do 57 | html.css('[rel~=start]').size.must_equal 1 58 | end 59 | 60 | it "has two items with rel prev value" do 61 | html.css('[rel~=prev]').size.must_equal 2 62 | end 63 | 64 | it "has two items with rel next value" do 65 | html.css('[rel~=next]').size.must_equal 2 66 | end 67 | 68 | it "has an anchor within each non-active/non-disabled list item" do 69 | html.css('ul li:not(.active):not(.disabled)').each { |li| li.at_css('a').wont_be_nil } 70 | end 71 | 72 | it "uses a span element for the active page" do 73 | html.at_css('ul li.active span').wont_be_nil 74 | end 75 | 76 | it 'uses a span to wrap the ellipsis' do 77 | ellipsis = BootstrapPagination::BootstrapRenderer::ELLIPSIS 78 | html.at_css('li.disabled span', text: ellipsis).wont_be_nil 79 | end 80 | 81 | describe 'when on the first page' do 82 | let(:page) { 1 } 83 | 84 | it 'uses a span element for the (disabled) previous button' do 85 | html.at_css('li.disabled span', text: 'Previous Label').wont_be_nil 86 | end 87 | end 88 | 89 | describe 'when on the last page' do 90 | let(:page) { collection_size } 91 | 92 | it 'uses a span element for the (disabled) next button' do 93 | html.at_css('li.disabled span', text: 'Next Label').wont_be_nil 94 | end 95 | end 96 | 97 | it "has no outer pagination div" do 98 | html.at_css('div.pagination').must_be_nil 99 | end 100 | 101 | it "has an unordered list with the pagination class" do 102 | html.at_css('ul.pagination').wont_be_nil 103 | end 104 | 105 | describe "when specifying a custom class" do 106 | let(:class_opt) { "pagination-lg" } 107 | 108 | it "applies the class to the ul" do 109 | html.at_css("ul.pagination.pagination-lg").wont_be_nil 110 | end 111 | end 112 | 113 | describe "with link attribute specified" do 114 | let(:link_options) { {"data-remote" => true} } 115 | 116 | it "includes the link attribute" do 117 | html.at_css('li.prev a')["data-remote"].must_equal "true" 118 | end 119 | end 120 | end 121 | -------------------------------------------------------------------------------- /will_paginate-bootstrap.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "bootstrap_pagination/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "will_paginate-bootstrap" 7 | s.version = BootstrapPagination::VERSION 8 | s.authors = ["Nick Dainty"] 9 | s.email = ["nick@npad.co.uk"] 10 | s.homepage = "https://github.com/bootstrap-ruby/will_paginate-bootstrap" 11 | s.summary = %q{Integrates the Twitter Bootstrap pagination component with will_paginate} 12 | s.description = %q{This gem integrates the Twitter Bootstrap pagination component with the will_paginate pagination gem. Supports Rails and Sinatra.} 13 | s.license = "MIT" 14 | 15 | s.rubyforge_project = "will_paginate-bootstrap" 16 | 17 | s.files = `git ls-files`.split("\n") 18 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 19 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 20 | s.require_paths = ["lib"] 21 | 22 | s.add_runtime_dependency "will_paginate", ">= 3.0.3" 23 | end 24 | --------------------------------------------------------------------------------