21 | <%= will_paginate @collection, renderer: WillPaginateSemanticUi::Sinatra::Renderer %>
22 |
23 |
24 | EOHTML
25 | end
26 |
27 | def build_collection
28 | page = if params[:page].to_i > 0
29 | params[:page].to_i
30 | else
31 | 1
32 | end
33 |
34 | @collection = WillPaginate::Collection.new page, 10, 100000
35 | end
36 |
37 | get "/" do
38 | build_collection
39 | erb template
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/will_paginate_semantic_ui.gemspec:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | lib = File.expand_path('../lib', __FILE__)
3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4 | require 'will_paginate_semantic_ui/version'
5 |
6 | Gem::Specification.new do |spec|
7 | spec.name = "will_paginate_semantic_ui"
8 | spec.version = WillPaginateSemanticUi::VERSION
9 | spec.authors = ["Rafael Biriba"]
10 | spec.email = ["biribarj@gmail.com"]
11 | spec.description = "Integrates the Semantic UI pagination component with will_paginate"
12 | spec.summary = "Integrates the Semantic UI pagination component with will_paginate"
13 | spec.homepage = "https://github.com/rafaelbiriba/will_paginate_semantic_ui"
14 | spec.license = "MIT"
15 |
16 | spec.files = `git ls-files`.split($/).reject{ |f| f =~ /docs/ }
17 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19 | spec.require_paths = ["lib"]
20 |
21 | spec.add_dependency "will_paginate", "> 3.0.0"
22 | spec.add_development_dependency "bundler"
23 | spec.add_development_dependency "rake"
24 | spec.add_development_dependency "rspec"
25 | spec.add_development_dependency "nokogiri"
26 | spec.add_development_dependency "byebug"
27 | spec.add_development_dependency "coveralls"
28 | end
29 |
--------------------------------------------------------------------------------
/lib/will_paginate_semantic_ui/generic_renderer.rb:
--------------------------------------------------------------------------------
1 | module WillPaginateSemanticUi
2 | module GenericRenderer
3 | GAP = "…"
4 |
5 | def to_html
6 | list_items = pagination.map do |item|
7 | item.class == Integer ? page_number(item) : send(item)
8 | end.join(@options[:link_separator])
9 |
10 | tag("div", list_items, class: ul_class)
11 | end
12 |
13 | protected
14 |
15 | def page_number(page)
16 | classLink = "item"
17 | classLink += " active" if page == current_page
18 | link(page, page, {class: classLink})
19 | end
20 |
21 | def previous_or_next_page(page, classname)
22 | classLink = "icon item"
23 | unless page
24 | tag(:a, tag("i", "", class: "#{classname} chevron icon"), class: classLink + " disabled")
25 | else
26 | link(tag("i", "", class: "#{classname} chevron icon"), page, {class: classLink})
27 | end
28 | end
29 |
30 | def gap
31 | tag("div", GAP, class: "disabled item")
32 | end
33 |
34 | def previous_page
35 | num = @collection.current_page > 1 && @collection.current_page - 1
36 | previous_or_next_page(num, "left")
37 | end
38 |
39 | def next_page
40 | num = @collection.current_page < @collection.total_pages && @collection.current_page + 1
41 | previous_or_next_page(num, "right")
42 | end
43 |
44 | def ul_class
45 | ["pagination ui menu", @options[:class]].compact.join(" ")
46 | end
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | will_paginate_semantic_ui (2.1.1)
5 | will_paginate (> 3.0.0)
6 |
7 | GEM
8 | remote: https://rubygems.org/
9 | specs:
10 | bigdecimal (3.2.2)
11 | byebug (12.0.0)
12 | coveralls (0.8.23)
13 | json (>= 1.8, < 3)
14 | simplecov (~> 0.16.1)
15 | term-ansicolor (~> 1.3)
16 | thor (>= 0.19.4, < 2.0)
17 | tins (~> 1.6)
18 | diff-lcs (1.6.2)
19 | docile (1.4.1)
20 | json (2.12.2)
21 | nokogiri (1.18.8-aarch64-linux-gnu)
22 | racc (~> 1.4)
23 | nokogiri (1.18.8-aarch64-linux-musl)
24 | racc (~> 1.4)
25 | nokogiri (1.18.8-arm-linux-gnu)
26 | racc (~> 1.4)
27 | nokogiri (1.18.8-arm-linux-musl)
28 | racc (~> 1.4)
29 | nokogiri (1.18.8-arm64-darwin)
30 | racc (~> 1.4)
31 | nokogiri (1.18.8-x86_64-darwin)
32 | racc (~> 1.4)
33 | nokogiri (1.18.8-x86_64-linux-gnu)
34 | racc (~> 1.4)
35 | nokogiri (1.18.8-x86_64-linux-musl)
36 | racc (~> 1.4)
37 | racc (1.8.1)
38 | rake (13.3.0)
39 | rspec (3.13.1)
40 | rspec-core (~> 3.13.0)
41 | rspec-expectations (~> 3.13.0)
42 | rspec-mocks (~> 3.13.0)
43 | rspec-core (3.13.4)
44 | rspec-support (~> 3.13.0)
45 | rspec-expectations (3.13.5)
46 | diff-lcs (>= 1.2.0, < 2.0)
47 | rspec-support (~> 3.13.0)
48 | rspec-mocks (3.13.5)
49 | diff-lcs (>= 1.2.0, < 2.0)
50 | rspec-support (~> 3.13.0)
51 | rspec-support (3.13.4)
52 | simplecov (0.16.1)
53 | docile (~> 1.1)
54 | json (>= 1.8, < 3)
55 | simplecov-html (~> 0.10.0)
56 | simplecov-html (0.10.2)
57 | sync (0.5.0)
58 | term-ansicolor (1.11.2)
59 | tins (~> 1.0)
60 | thor (1.3.2)
61 | tins (1.38.0)
62 | bigdecimal
63 | sync
64 | will_paginate (4.0.1)
65 |
66 | PLATFORMS
67 | aarch64-linux-gnu
68 | aarch64-linux-musl
69 | arm-linux-gnu
70 | arm-linux-musl
71 | arm64-darwin
72 | x86_64-darwin
73 | x86_64-linux-gnu
74 | x86_64-linux-musl
75 |
76 | DEPENDENCIES
77 | bundler
78 | byebug
79 | coveralls
80 | nokogiri
81 | rake
82 | rspec
83 | will_paginate_semantic_ui!
84 |
85 | BUNDLED WITH
86 | 2.6.9
87 |
--------------------------------------------------------------------------------
/spec/lib/will_paginate_semantic_ui/generic_renderer_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 | require 'nokogiri'
3 | require 'will_paginate/array'
4 |
5 | include WillPaginate::ViewHelpers
6 |
7 | describe WillPaginateSemanticUi::GenericRenderer do
8 | let(:collection_size) { 15 }
9 | let(:page) { (collection_size / 2.0).to_i }
10 | let(:collection) { 1.upto(collection_size).to_a }
11 | let(:class_opt) { nil }
12 | let(:output) do
13 | will_paginate(collection.paginate(:page => page, :per_page => 1), renderer: FakeRenderer, class: class_opt)
14 | end
15 |
16 | let(:html) { Nokogiri::HTML.fragment(output) }
17 |
18 | it "returns a string" do
19 | expect(output).to be_kind_of String
20 | end
21 |
22 | it "returns a string containing HTML" do
23 | expect(html).to be_kind_of Nokogiri::HTML::DocumentFragment
24 | end
25 |
26 | it "has an active list item" do
27 | expect(html.at_css('div a.active.item')).not_to be_nil
28 | end
29 |
30 | it "has a gap item with class disabled" do
31 | expect(html.at_css('div.disabled.item')).not_to be_nil
32 | end
33 |
34 | it "has two items with rel prev value" do
35 | expect(html.css('[rel~=prev]').size).to eql 2
36 | end
37 |
38 | it "has two items with rel next value" do
39 | expect(html.css('[rel~=next]').size).to eql 2
40 | end
41 |
42 | it "has an anchor within each non-active/non-disabled list item" do
43 | html.css('div a:not(.active):not(.disabled)').each { |a| expect(a).not_to be_nil }
44 | end
45 |
46 | it 'has a ellipsis in the gap' do
47 | ellipsis = FakeRenderer::GAP
48 | expect(html.at_css('div.disabled', text: ellipsis)).not_to be_nil
49 | end
50 |
51 | describe 'when on the first page' do
52 | let(:page) { 1 }
53 |
54 | it 'uses a i element for the (disabled) previous button' do
55 | expect(html.at_css('a.disabled i.left')).not_to be_nil
56 | end
57 | end
58 |
59 | describe 'when on the last page' do
60 | let(:page) { collection_size }
61 |
62 | it 'uses a i element for the (disabled) next button' do
63 | expect(html.at_css('a.disabled i.right')).not_to be_nil
64 | end
65 | end
66 |
67 | it "has a div with pagination class" do
68 | expect(html.at_css('div.pagination.ui.menu')).not_to be_nil
69 | end
70 |
71 | describe "when specifying a custom class" do
72 | let(:class_opt) { "pagination-lg" }
73 |
74 | it "applies the class to the ul" do
75 | expect(html.at_css("div.pagination.ui.menu.pagination-lg")).not_to be_nil
76 | end
77 | end
78 | end
79 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Will Paginate for Semantic UI
2 |
3 |  [](https://codeclimate.com/github/rafaelbiriba/will_paginate_semantic_ui) [](https://coveralls.io/r/rafaelbiriba/will_paginate_semantic_ui?branch=master) [](https://travis-ci.org/rafaelbiriba/will_paginate_semantic_ui)
4 |
5 | #### If you are using [Will Paginate gem](https://github.com/mislav/will_paginate) and [Semantic UI framework](http://semantic-ui.com/), this gem is WHAT YOU NEED!
6 |
7 | The html snippet for pagination that `will_paginate` creates is incompatible with the semantic ui.
8 |
9 | This gem solves this problem with a custom render that creates the correct pagination html for the component.
10 |
11 | 
12 | 
13 |
14 | ## Requirements
15 |
16 | Semantic UI `> 2.0` and will_paginate `> 3.0`
17 |
18 | ## Installation
19 |
20 | As easy as `gem install will_paginate_semantic_ui` or add `gem "will_paginate_semantic_ui"` to your Gemfile
21 |
22 | ## How to use
23 |
24 | ### Rails
25 |
26 | In your paginated view, you need to use another render in the will paginate command:
27 |
28 | `<%= will_paginate @collection, renderer: WillPaginateSemanticUi::ActionView::Renderer %>`
29 |
30 | ### Sinatra
31 |
32 | `require "will_paginate_semantic_ui"` in your Sinatra app.
33 |
34 | In your paginated view, you need to use another render in the will paginate command:
35 |
36 | `<%= will_paginate @collection, renderer: WillPaginateSemanticUi::Sinatra::Renderer %>`
37 |
38 | **Look the example implementation at** `docs/sinatra_example`
39 |
40 | 
41 |
42 | To run the example:
43 |
44 | ```
45 | cd docs/sinatra_example
46 | bundle install
47 | rackup
48 | ```
49 |
50 | ## Tuning
51 |
52 | You can also use some will_pagination options to customize your component:
53 |
54 | `<%= will_paginate @collection, renderer: WillPaginateSemanticUi::ActionView::Renderer, class: "right floated", inner_window: 3 %>
55 | `
56 |
57 | The command above create this
58 |
59 | 
60 |
61 | `inner_window: 3` as you see above, 3 pages to the left and to the right from the selected page. (This creates a component with 700px max width in the worst case)
62 |
63 | 
64 |
65 | `class: "right floated"` useful if you are using inside a table. Floats the pagination to the right.
66 |
67 | ## Contributing
68 |
69 | First of all, **thank you** for wanting to help!
70 |
71 | 1. [Fork it](https://help.github.com/articles/fork-a-repo).
72 | 2. Create a feature branch - `git checkout -b more_magic`
73 | 3. Add tests and make your changes
74 | 4. Check if tests are ok - `rake spec`
75 | 5. Commit changes - `git commit -am "Added more magic"`
76 | 6. Push to Github - `git push origin more_magic`
77 | 7. Send a [pull request](https://help.github.com/articles/using-pull-requests)! :heart:
78 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require "rake"
2 | require "byebug"
3 | require "will_paginate_semantic_ui"
4 | require 'coveralls'
5 | Coveralls.wear!
6 |
7 | # This file was generated by the `rspec --init` command. Conventionally, all
8 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
9 | # The generated `.rspec` file contains `--require spec_helper` which will cause
10 | # this file to always be loaded, without a need to explicitly require it in any
11 | # files.
12 | #
13 | # Given that it is always loaded, you are encouraged to keep this file as
14 | # light-weight as possible. Requiring heavyweight dependencies from this file
15 | # will add to the boot time of your test suite on EVERY test run, even for an
16 | # individual file that may not need all of that loaded. Instead, consider making
17 | # a separate helper file that requires the additional dependencies and performs
18 | # the additional setup, and require it from the spec files that actually need
19 | # it.
20 | #
21 | # The `.rspec` file also contains a few flags that are not defaults but that
22 | # users commonly want.
23 | #
24 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
25 | RSpec.configure do |config|
26 | # rspec-expectations config goes here. You can use an alternate
27 | # assertion/expectation library such as wrong or the stdlib/minitest
28 | # assertions if you prefer.
29 | config.expect_with :rspec do |expectations|
30 | # This option will default to `true` in RSpec 4. It makes the `description`
31 | # and `failure_message` of custom matchers include text for helper methods
32 | # defined using `chain`, e.g.:
33 | # be_bigger_than(2).and_smaller_than(4).description
34 | # # => "be bigger than 2 and smaller than 4"
35 | # ...rather than:
36 | # # => "be bigger than 2"
37 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true
38 | end
39 |
40 | # rspec-mocks config goes here. You can use an alternate test double
41 | # library (such as bogus or mocha) by changing the `mock_with` option here.
42 | config.mock_with :rspec do |mocks|
43 | # Prevents you from mocking or stubbing a method that does not exist on
44 | # a real object. This is generally recommended, and will default to
45 | # `true` in RSpec 4.
46 | mocks.verify_partial_doubles = true
47 | end
48 |
49 | # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
50 | # have no way to turn it off -- the option exists only for backwards
51 | # compatibility in RSpec 3). It causes shared context metadata to be
52 | # inherited by the metadata hash of host groups and examples, rather than
53 | # triggering implicit auto-inclusion in groups with matching metadata.
54 | config.shared_context_metadata_behavior = :apply_to_host_groups
55 |
56 | # The settings below are suggested to provide a good initial experience
57 | # with RSpec, but feel free to customize to your heart's content.
58 | =begin
59 | # This allows you to limit a spec run to individual examples or groups
60 | # you care about by tagging them with `:focus` metadata. When nothing
61 | # is tagged with `:focus`, all examples get run. RSpec also provides
62 | # aliases for `it`, `describe`, and `context` that include `:focus`
63 | # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
64 | config.filter_run_when_matching :focus
65 |
66 | # Allows RSpec to persist some state between runs in order to support
67 | # the `--only-failures` and `--next-failure` CLI options. We recommend
68 | # you configure your source control system to ignore this file.
69 | config.example_status_persistence_file_path = "spec/examples.txt"
70 |
71 | # Limits the available syntax to the non-monkey patched syntax that is
72 | # recommended. For more details, see:
73 | # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
74 | # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
75 | # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
76 | config.disable_monkey_patching!
77 |
78 | # This setting enables warnings. It's recommended, but in some cases may
79 | # be too noisy due to issues in dependencies.
80 | config.warnings = true
81 |
82 | # Many RSpec users commonly either run the entire suite or an individual
83 | # file, and it's useful to allow more verbose output when running an
84 | # individual spec file.
85 | if config.files_to_run.one?
86 | # Use the documentation formatter for detailed output,
87 | # unless a formatter has already been configured
88 | # (e.g. via a command-line flag).
89 | config.default_formatter = 'doc'
90 | end
91 |
92 | # Print the 10 slowest examples and example groups at the
93 | # end of the spec run, to help surface which specs are running
94 | # particularly slow.
95 | config.profile_examples = 10
96 |
97 | # Run specs in random order to surface order dependencies. If you find an
98 | # order dependency and want to debug it, you can fix the order by providing
99 | # the seed, which is printed after each run.
100 | # --seed 1234
101 | config.order = :random
102 |
103 | # Seed global randomization in this process using the `--seed` CLI option.
104 | # Setting this allows you to use `--seed` to deterministically reproduce
105 | # test failures related to randomization by passing the same `--seed` value
106 | # as the one that triggered the failure.
107 | Kernel.srand config.seed
108 | =end
109 | end
110 |
111 | Dir["./spec/support/**/*.rb"].each { |f| require f }
112 |
--------------------------------------------------------------------------------