foliate 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8e632e2cdf928b30535057da735d185e35d5bb80
4
+ data.tar.gz: dcaed853a25f108a2838ad7c686a9e389e55cdb2
5
+ SHA512:
6
+ metadata.gz: b34de5919e49576e9a4c27b84488d179a2a021e618dcbbec69707121023a12fb2ca69eb9a2d0e3058687602bbe2dcde50ffe4b5a058239fe2d2efe006f4ff32a
7
+ data.tar.gz: 3b8719a28e535fd8ba94b0ec5bcf78a43451d01ba34172c87389bf05217100aceb042e21888a57232dffec8732c40aa483620427fb95adcb64656128527c708d
@@ -0,0 +1,20 @@
1
+ Copyright 2017
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.
@@ -0,0 +1,106 @@
1
+ # foliate
2
+
3
+ Pagination for Ruby on Rails.
4
+
5
+ **Why another pagination library?** Because a different approach leads
6
+ to a cleaner and much simpler implementation.
7
+
8
+ **How is it different?** Instead of extending ActiveRecord, or
9
+ dynamically defining methods on objects after instantiating them,
10
+ *foliate* adds a single method to ActionController:
11
+
12
+ ```ruby
13
+ ## app/controllers/posts_controller.rb
14
+ class PostsController < ApplicationController
15
+
16
+ def index
17
+ @posts = paginate(Post) # <-- single method
18
+ end
19
+
20
+ end
21
+ ```
22
+
23
+ Calling `paginate` with something like an ActiveRecord::Relation (or an
24
+ Array) returns an ActiveRecord::Relation (or an Array) scoped to the
25
+ current page of records, as dictated by `params[:page]`.
26
+
27
+ Calling `paginate` also sets a `@pagination` instance variable for use
28
+ in the view. This object can be passed directly to `render`, which will
29
+ then render the "app/views/pagination/_pagination.html.erb" view
30
+ partial:
31
+
32
+ ```html
33
+ <!-- app/views/posts/index.html.erb -->
34
+
35
+ Do something with @posts here...
36
+
37
+ <%= render @pagination %>
38
+ ```
39
+
40
+ **How does that look?** By default, something like this:
41
+
42
+ <img src="screenshots/page_input.png" alt="page input pagination">
43
+
44
+
45
+ ## More Information
46
+
47
+ **How do I customize the appearance of the pagination?** Running the
48
+ *foliate* installation generator creates
49
+ "app/views/pagination/_pagination.html.erb" and
50
+ "app/assets/stylesheets/pagination.css" in your project directory.
51
+ These files can be edited to meet your needs.
52
+
53
+ **How many records are in each page?** By default, *foliate* allots
54
+ `Foliate.config.default_per_page` records per page, which is set in
55
+ "config/initializers/foliate.rb". However, this can be overridden by
56
+ passing `per_page:` to `paginate`:
57
+
58
+ ```ruby
59
+ @posts = paginate(Post, per_page: 50)
60
+ ```
61
+
62
+ **What if I have a very large table, and don't want to incur a count of
63
+ all records for each page?** The `paginate` method accepts a
64
+ `total_records:` argument, which will prevent a SQL count when set:
65
+
66
+ ```ruby
67
+ @posts = paginate(Post, total_records: Post.cached_count)
68
+ ```
69
+
70
+ **What if I want a different param than `:page` to dictate the current
71
+ page?** That can be configured with `Foliate.config.page_param`, which
72
+ is set in "config/initializers/foliate.rb".
73
+
74
+ **For even more information,** see the
75
+ [full documentation](http://www.rubydoc.info/gems/foliate/).
76
+
77
+
78
+ ## Installation
79
+
80
+ Add this line to your application's Gemfile:
81
+
82
+ ```ruby
83
+ gem "foliate"
84
+ ```
85
+
86
+ Then execute:
87
+
88
+ ```bash
89
+ $ bundle
90
+ ```
91
+
92
+ And finally, run the installation generator:
93
+
94
+ ```bash
95
+ $ rails generate foliate:install
96
+ ```
97
+
98
+
99
+ ## Contributing
100
+
101
+ Run `rake test` to run the tests.
102
+
103
+
104
+ ## License
105
+
106
+ [MIT License](https://opensource.org/licenses/MIT)
@@ -0,0 +1,29 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'yard'
8
+
9
+ YARD::Rake::YardocTask.new(:doc) do |t|
10
+ end
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+ require 'bundler/gem_tasks'
19
+
20
+ require 'rake/testtask'
21
+
22
+ Rake::TestTask.new(:test) do |t|
23
+ t.libs << 'test'
24
+ t.pattern = 'test/**/*_test.rb'
25
+ t.verbose = false
26
+ end
27
+
28
+
29
+ task default: :test
@@ -0,0 +1,3 @@
1
+ require "foliate/version"
2
+ require "foliate/config"
3
+ require "foliate/railtie"
@@ -0,0 +1,31 @@
1
+ module Foliate
2
+
3
+ class Config
4
+ # @return [Integer]
5
+ # default number of records to allot per page (defaults to +10+)
6
+ attr_accessor :default_per_page
7
+
8
+ # @return [Symbol]
9
+ # URL query param name for specifying page numbers (defaults to
10
+ # +:page+)
11
+ attr_accessor :page_param
12
+
13
+ def initialize
14
+ @default_per_page = 10
15
+ @page_param = :page
16
+ end
17
+ end
18
+
19
+ # Foliate global configuration object.
20
+ #
21
+ # @return [Foliate::Config]
22
+ def self.config
23
+ @config ||= Foliate::Config.new
24
+ end
25
+
26
+ # @param c [Foliate::Config]
27
+ def self.config=(c)
28
+ @config = c
29
+ end
30
+
31
+ end
@@ -0,0 +1,61 @@
1
+ require "foliate/config"
2
+ require "foliate/pagination"
3
+
4
+ module Foliate
5
+ module Controller
6
+
7
+ # Paginates +records+, and returns the current page of records
8
+ # according to <code>params[Foliate.config.page_param]</code>
9
+ # (typically, <code>params[:page]</code>). Also sets the
10
+ # +@pagination+ instance variable for use in the view (see
11
+ # {Foliate::Pagination}).
12
+ #
13
+ # Returns an ActiveRecord::Relation if +records+ is an
14
+ # ActiveRecord::Relation. Returns an Array if +records+ is an
15
+ # Array.
16
+ #
17
+ # By default, allots <code>Foliate.config.default_per_page</code>
18
+ # number of records per page. This can be overridden by specifying
19
+ # +per_page:+.
20
+ #
21
+ # By default, if +records+ is an ActiveRecord::Relation, computes
22
+ # the total number of pages by performing a SQL count query. If the
23
+ # underlying table is very large, this query could have a noticeable
24
+ # performance cost. This can be circumvented by specifying
25
+ # +total_records:+, using an estimated or cached record count.
26
+ #
27
+ # @example basic pagination
28
+ # @posts = paginate(Post)
29
+ #
30
+ # @example paginated search
31
+ # @posts = paginate(Post.where(status: params[:show_only]))
32
+ #
33
+ # @example user-specified per_page
34
+ # @posts = paginate(Post, per_page: params[:at_a_time])
35
+ #
36
+ # @example simple cached count
37
+ # count = Rails.cache.fetch("Post/count", expires_in: 5.minutes){ Post.count }
38
+ # @posts = paginate(Post, total_records: count)
39
+ #
40
+ # @param records [ActiveRecord::Relation, Array]
41
+ # @param per_page [Integer, String]
42
+ # @param total_records [Integer]
43
+ # @return [ActiveRecord::Relation, Array]
44
+ def paginate(records, per_page: nil, total_records: nil)
45
+ @pagination = Foliate::Pagination.new.tap do |p|
46
+ p.current_page = [params[Foliate.config.page_param].to_i, 1].max
47
+ p.per_page = per_page.try(&:to_i) || Foliate.config.default_per_page
48
+ p.total_records = total_records || (records.is_a?(Array) ?
49
+ records.length : records.unscope(:limit).unscope(:offset).count)
50
+ p.controller = params[:controller]
51
+ p.action = params[:action]
52
+ p.query_params = request.query_parameters.except(Foliate.config.page_param)
53
+ end
54
+
55
+ records.is_a?(Array) ?
56
+ records[@pagination.offset, @pagination.per_page].to_a :
57
+ records.limit(@pagination.per_page).offset(@pagination.offset)
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,111 @@
1
+ require "foliate/config"
2
+
3
+ module Foliate
4
+ class Pagination
5
+
6
+ # @return [Integer]
7
+ # current page number
8
+ attr_accessor :current_page
9
+
10
+ # @return [Integer]
11
+ # number of records per page
12
+ attr_accessor :per_page
13
+
14
+ # @return [Integer]
15
+ # total number of records
16
+ attr_accessor :total_records
17
+
18
+ # @return [Symbol]
19
+ # originating controller
20
+ attr_accessor :controller
21
+
22
+ # @return [Symbol]
23
+ # originating controller action
24
+ attr_accessor :action
25
+
26
+ # @return [Hash]
27
+ # originating request query params
28
+ attr_accessor :query_params
29
+
30
+ # Computes the total number of pages based on +total_records+ and
31
+ # +per_page+.
32
+ #
33
+ # @return [Integer]
34
+ def total_pages
35
+ (total_records / per_page.to_f).ceil
36
+ end
37
+
38
+ # Computes the record set offset based on +current_page+ and
39
+ # +per_page+.
40
+ #
41
+ # @return [Integer]
42
+ def offset
43
+ (current_page - 1) * per_page
44
+ end
45
+
46
+ # Returns linking params for a specified +page_number+. The
47
+ # returned Hash is intended for use with +link_to+, +url_for+, etc.
48
+ #
49
+ # @example usage in view
50
+ # link_to "First", pagination.params_for_page(1)
51
+ # link_to "Last", pagination.params_for_page(pagination.total_pages)
52
+ #
53
+ # @param page_number [Integer]
54
+ # @return [Hash]
55
+ def params_for_page(page_number)
56
+ { controller: controller, action: action, params: query_params.merge(
57
+ Foliate.config.page_param => (page_number if page_number > 1)
58
+ ) }
59
+ end
60
+
61
+ # Indicates if there is an expected page previous to the current
62
+ # page.
63
+ #
64
+ # @return [Boolean]
65
+ def prev?
66
+ current_page > 1
67
+ end
68
+
69
+ # Indicates if there is an expected page beyond the current page.
70
+ #
71
+ # @return [Boolean]
72
+ def next?
73
+ current_page < total_pages
74
+ end
75
+
76
+ # Linking params for the previous page. Returns nil if {#prev?} is
77
+ # false. See also {#params_for_page}.
78
+ #
79
+ # @example usage in view
80
+ # link_to_if pagination.prev?, "Previous", pagination.prev_page_params
81
+ #
82
+ # @return [Hash, nil]
83
+ def prev_page_params
84
+ params_for_page(current_page - 1) if prev?
85
+ end
86
+
87
+ # Linking params for the next page. Returns nil if {#next?} is
88
+ # false. See also {#params_for_page}.
89
+ #
90
+ # @example usage in view
91
+ # link_to_if pagination.next?, "Next", pagination.next_page_params
92
+ #
93
+ # @return [Hash, nil]
94
+ def next_page_params
95
+ params_for_page(current_page + 1) if next?
96
+ end
97
+
98
+ # Path to the view partial. This method exists to allow
99
+ # +Pagination+ objects to be passed directly to +render+ calls in
100
+ # the view.
101
+ #
102
+ # @example rendering view partial from view
103
+ # render @pagination
104
+ #
105
+ # @return [String]
106
+ def to_partial_path
107
+ "pagination/pagination"
108
+ end
109
+
110
+ end
111
+ end
@@ -0,0 +1,12 @@
1
+ require "rails/railtie"
2
+ require "foliate/controller"
3
+
4
+ module Foliate
5
+ class Railtie < Rails::Railtie
6
+ initializer :foliate do |app|
7
+ ActiveSupport.on_load :action_controller do
8
+ ActionController::Base.send :include, Foliate::Controller
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Foliate
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,20 @@
1
+ require "foliate/config"
2
+ require "rails/generators/base"
3
+
4
+ module Foliate
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ source_root File.join(__dir__, "templates")
8
+
9
+ def copy_config
10
+ template "config/initializer.rb.erb", "config/initializers/foliate.rb"
11
+ copy_file "config/locales.yml", "config/locales/foliate.yml"
12
+ end
13
+
14
+ def copy_view
15
+ copy_file "views/page_input.html.erb", "app/views/pagination/_pagination.html.erb"
16
+ copy_file "stylesheets/page_input.css", "app/assets/stylesheets/pagination.css"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ Foliate.config.tap do |config|
2
+ config.default_per_page = <%= Foliate.config.default_per_page.inspect %>
3
+ config.page_param = <%= Foliate.config.page_param.inspect %>
4
+ end
@@ -0,0 +1,5 @@
1
+ en:
2
+ foliate:
3
+ prev: "Previous"
4
+ next: "Next"
5
+ of: "of"
@@ -0,0 +1,26 @@
1
+ .foliate-page-link {
2
+ color: rgba(0, 0, 0, 0.6);
3
+ }
4
+
5
+ .foliate-i-of-n {
6
+ margin: 0 1em;
7
+ }
8
+
9
+ .foliate-form {
10
+ display: inline-block;
11
+ margin: 0;
12
+ }
13
+
14
+ .foliate-page-input {
15
+ font-size: 1em;
16
+ width: 2.5em;
17
+ border: 1px solid rgba(0, 0, 0, 0.5);
18
+ border-radius: 2px;
19
+ line-height: 1.5em;
20
+ text-align: center;
21
+ font-family: monospace;
22
+ }
23
+
24
+ .foliate-of {
25
+ margin: 0 0.25em;
26
+ }
@@ -0,0 +1,25 @@
1
+ <div class="foliate-pagination">
2
+ <span class="foliate-page-link foliate-prev-link">
3
+ <%= link_to_if pagination.prev?, t("foliate.prev"), pagination.prev_page_params %>
4
+ </span>
5
+
6
+ <span class="foliate-i-of-n">
7
+ <form method="get" class="foliate-form">
8
+ <% pagination.query_params.each do |name, value| %>
9
+ <input type="hidden" name="<%= name %>" value="<%= value %>">
10
+ <% end %>
11
+
12
+ <input type="text" pattern="[0-9]*" class="foliate-page-input"
13
+ name="<%= Foliate.config.page_param %>"
14
+ value="<%= pagination.current_page %>">
15
+ </form>
16
+
17
+ <span class="foliate-of"><%= t("foliate.of") %></span>
18
+
19
+ <span class="foliate-total-pages"><%= pagination.total_pages %></span>
20
+ </span>
21
+
22
+ <span class="foliate-page-link foliate-next-link">
23
+ <%= link_to_if pagination.next?, t("foliate.next"), pagination.next_page_params %>
24
+ </span>
25
+ </div>
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: foliate
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Hefner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-11-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ description:
56
+ email:
57
+ - jonathan.hefner@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - MIT-LICENSE
63
+ - README.md
64
+ - Rakefile
65
+ - lib/foliate.rb
66
+ - lib/foliate/config.rb
67
+ - lib/foliate/controller.rb
68
+ - lib/foliate/pagination.rb
69
+ - lib/foliate/railtie.rb
70
+ - lib/foliate/version.rb
71
+ - lib/generators/foliate/install/install_generator.rb
72
+ - lib/generators/foliate/install/templates/config/initializer.rb.erb
73
+ - lib/generators/foliate/install/templates/config/locales.yml
74
+ - lib/generators/foliate/install/templates/stylesheets/page_input.css
75
+ - lib/generators/foliate/install/templates/views/page_input.html.erb
76
+ homepage: https://github.com/jonathanhefner/foliate
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.6.13
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Rails pagination
100
+ test_files: []