pagy 5.0.0 → 5.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/config/pagy.rb +6 -1
- data/lib/javascripts/pagy.js +1 -1
- data/lib/pagy/backend.rb +3 -2
- data/lib/pagy/console.rb +2 -1
- data/lib/pagy/countless.rb +11 -6
- data/lib/pagy/exceptions.rb +15 -13
- data/lib/pagy/extras/bootstrap.rb +3 -0
- data/lib/pagy/extras/bulma.rb +3 -0
- data/lib/pagy/extras/countless.rb +4 -7
- data/lib/pagy/extras/elasticsearch_rails.rb +3 -3
- data/lib/pagy/extras/foundation.rb +3 -0
- data/lib/pagy/extras/gearbox.rb +1 -1
- data/lib/pagy/extras/items.rb +3 -3
- data/lib/pagy/extras/materialize.rb +3 -0
- data/lib/pagy/extras/meilisearch.rb +3 -3
- data/lib/pagy/extras/metadata.rb +6 -28
- data/lib/pagy/extras/navs.rb +2 -0
- data/lib/pagy/extras/overflow.rb +3 -4
- data/lib/pagy/extras/searchkick.rb +3 -3
- data/lib/pagy/extras/semantic.rb +3 -0
- data/lib/pagy/extras/shared.rb +3 -4
- data/lib/pagy/extras/standalone.rb +15 -12
- data/lib/pagy/extras/support.rb +6 -0
- data/lib/pagy/extras/trim.rb +2 -1
- data/lib/pagy/extras/uikit.rb +3 -0
- data/lib/pagy/frontend.rb +3 -2
- data/lib/pagy/i18n.rb +2 -2
- data/lib/pagy/url_helpers.rb +10 -8
- data/lib/pagy.rb +4 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4af6c795ba446552a412f0f45e76a267cf767d8f4dec3564a90096525bb298ea
|
4
|
+
data.tar.gz: 57a3f62877f0ed653ebe68f59963fb865e252e68c55e5c3a91794b9aa3b9584a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0520f9933ea293895b8d26b0a78ea0af1a61054b5b89fce3a06c1f8f292d82357f6e105f76ab7bd4665f6ee9765bc69ce284428b8fe61b8f0a6b4768136c8e4a
|
7
|
+
data.tar.gz: '0903950d58220f510b5c2700b42f23f19c5cd267bc73eb5404d918863717b816836609256ef3a340534a9bc74e50260915b8b023b502c9dbe503bb443fab968f'
|
data/lib/config/pagy.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Pagy initializer file (5.
|
3
|
+
# Pagy initializer file (5.1.2)
|
4
4
|
# Customize only what you really need and notice that Pagy works also without any of the following lines.
|
5
5
|
# Should you just cherry pick part of this file, please maintain the require-order of the extras
|
6
6
|
|
@@ -153,6 +153,11 @@
|
|
153
153
|
# set to false only if you want to make :trim_extra an opt-in variable
|
154
154
|
# Pagy::DEFAULT[:trim_extra] = false # default true
|
155
155
|
|
156
|
+
# Standalone extra: Use pagy in non Rack environment/gem
|
157
|
+
# See https://ddnexus.github.io/pagy/extras/standalone
|
158
|
+
# require 'pagy/extras/standalone'
|
159
|
+
# Pagy::DEFAULT[:url] = 'http://www.example.com/subdir' # optional default
|
160
|
+
|
156
161
|
|
157
162
|
# Rails
|
158
163
|
|
data/lib/javascripts/pagy.js
CHANGED
data/lib/pagy/backend.rb
CHANGED
@@ -15,16 +15,17 @@ class Pagy
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# Sub-method called only by #pagy: here for easy customization of variables by overriding
|
18
|
+
# You may need to override the count call for non AR collections
|
18
19
|
def pagy_get_vars(collection, vars)
|
19
20
|
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
20
|
-
vars[:count] ||= (
|
21
|
+
vars[:count] ||= (count = collection.count(:all)).is_a?(Hash) ? count.size : count
|
21
22
|
vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
|
22
23
|
vars
|
23
24
|
end
|
24
25
|
|
25
26
|
# Sub-method called only by #pagy: here for easy customization of record-extraction by overriding
|
27
|
+
# You may need to override this method for collections without offset|limit
|
26
28
|
def pagy_get_items(collection, pagy)
|
27
|
-
# This should work with ActiveRecord, Sequel, Mongoid...
|
28
29
|
collection.offset(pagy.offset).limit(pagy.items)
|
29
30
|
end
|
30
31
|
end
|
data/lib/pagy/console.rb
CHANGED
@@ -5,8 +5,9 @@ require 'pagy' # so you can require just the extra in the console
|
|
5
5
|
require 'pagy/extras/standalone'
|
6
6
|
|
7
7
|
class Pagy
|
8
|
-
# Provide ready to use pagy environment when included in irb/rails console
|
8
|
+
# Provide a ready to use pagy environment when included in irb/rails console
|
9
9
|
module Console
|
10
|
+
# Include Backend, Frontend and set the default URL
|
10
11
|
def self.included(main)
|
11
12
|
main.include(Backend)
|
12
13
|
main.include(Frontend)
|
data/lib/pagy/countless.rb
CHANGED
@@ -14,18 +14,23 @@ class Pagy
|
|
14
14
|
@offset = (@items * (@page - 1)) + @outset
|
15
15
|
end
|
16
16
|
|
17
|
-
# Finalize the instance variables based on the fetched
|
18
|
-
def finalize(
|
19
|
-
raise OverflowError.new(self
|
20
|
-
if fetched.zero? && @page > 1
|
17
|
+
# Finalize the instance variables based on the fetched size
|
18
|
+
def finalize(fetched_size)
|
19
|
+
raise OverflowError.new(self, :page, "to be < #{@page}") if fetched_size.zero? && @page > 1
|
21
20
|
|
22
|
-
@pages = @last = (
|
23
|
-
@in = [
|
21
|
+
@pages = @last = (fetched_size > @items ? @page + 1 : @page)
|
22
|
+
@in = [fetched_size, @items].min
|
24
23
|
@from = @in.zero? ? 0 : @offset - @outset + 1
|
25
24
|
@to = @offset - @outset + @in
|
26
25
|
@prev = (@page - 1 unless @page == 1)
|
27
26
|
@next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
|
28
27
|
self
|
29
28
|
end
|
29
|
+
|
30
|
+
# Override the original series.
|
31
|
+
# Return nil if :countless_minimal is enabled
|
32
|
+
def series(_size = @vars[:size])
|
33
|
+
super unless @vars[:countless_minimal]
|
34
|
+
end
|
30
35
|
end
|
31
36
|
end
|
data/lib/pagy/exceptions.rb
CHANGED
@@ -3,23 +3,25 @@
|
|
3
3
|
class Pagy
|
4
4
|
# Generic variable error
|
5
5
|
class VariableError < ArgumentError
|
6
|
-
attr_reader :pagy
|
6
|
+
attr_reader :pagy, :variable, :value
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
@pagy
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
message
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def value
|
19
|
-
pagy.vars[variable]
|
8
|
+
# Set the variables and prepare the message
|
9
|
+
def initialize(pagy, variable, description, value = nil)
|
10
|
+
@pagy = pagy
|
11
|
+
@variable = variable
|
12
|
+
@value = value
|
13
|
+
message = +"expected :#{@variable} #{description}"
|
14
|
+
message << "; got #{@value.inspect}" if value
|
15
|
+
super message
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
23
19
|
# Specific overflow error
|
24
20
|
class OverflowError < VariableError; end
|
21
|
+
|
22
|
+
# I18n configuration error
|
23
|
+
class I18nError < StandardError; end
|
24
|
+
|
25
|
+
# Generic internal error
|
26
|
+
class InternalError < StandardError; end
|
25
27
|
end
|
@@ -4,6 +4,8 @@
|
|
4
4
|
require 'pagy/extras/shared'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
7
9
|
module BootstrapExtra
|
8
10
|
# Pagination for bootstrap: it returns the html with the series of links to the pages
|
9
11
|
def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '')
|
@@ -20,6 +22,7 @@ class Pagy
|
|
20
22
|
%(<li class="page-item active">#{link.call item}</li>)
|
21
23
|
when :gap
|
22
24
|
%(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
|
25
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
23
26
|
end
|
24
27
|
end
|
25
28
|
html << pagy_bootstrap_next_html(pagy, link)
|
data/lib/pagy/extras/bulma.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
require 'pagy/extras/shared'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
7
9
|
module BulmaExtra
|
8
10
|
# Pagination for Bulma: it returns the html with the series of links to the pages
|
9
11
|
def pagy_bulma_nav(pagy, pagy_id: nil, link_extra: '')
|
@@ -22,6 +24,7 @@ class Pagy
|
|
22
24
|
%(class="pagination-link is-current" aria-label="page #{item}" aria-current="page")}</li>)
|
23
25
|
when :gap
|
24
26
|
%(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>)
|
27
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
25
28
|
end
|
26
29
|
end
|
27
30
|
html << %(</ul></nav>)
|
@@ -23,16 +23,13 @@ class Pagy
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# Sub-method called only by #pagy_countless: here for easy customization of record-extraction by overriding
|
26
|
+
# You may need to override this method for collections without offset|limit
|
26
27
|
def pagy_countless_get_items(collection, pagy)
|
27
|
-
# This should work with ActiveRecord, Sequel, Mongoid...
|
28
28
|
return collection.offset(pagy.offset).limit(pagy.items) if pagy.vars[:countless_minimal]
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# finalize may adjust pagy.items, so must be used after checking the size
|
34
|
-
pagy.finalize(items_size)
|
35
|
-
items
|
30
|
+
fetched = collection.offset(pagy.offset).limit(pagy.items + 1).to_a # eager load items + 1
|
31
|
+
pagy.finalize(fetched.size) # finalize the pagy object
|
32
|
+
fetched[0, pagy.items] # ignore eventual extra item
|
36
33
|
end
|
37
34
|
end
|
38
35
|
Backend.prepend CountlessExtra
|
@@ -19,8 +19,8 @@ class Pagy
|
|
19
19
|
|
20
20
|
module ElasticsearchRails
|
21
21
|
# Return an array used to delay the call of #search
|
22
|
-
# after the pagination variables are merged to the options
|
23
|
-
#
|
22
|
+
# after the pagination variables are merged to the options.
|
23
|
+
# It also pushes to the same array an optional method call.
|
24
24
|
def pagy_elasticsearch_rails(query_or_payload, **options)
|
25
25
|
[self, query_or_payload, options].tap do |args|
|
26
26
|
args.define_singleton_method(:method_missing) { |*a| args += a }
|
@@ -57,7 +57,7 @@ class Pagy
|
|
57
57
|
pagy = ::Pagy.new(vars)
|
58
58
|
# with :last_page overflow we need to re-run the method in order to get the hits
|
59
59
|
return pagy_elasticsearch_rails(pagy_search_args, vars.merge(page: pagy.page)) \
|
60
|
-
|
60
|
+
if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
|
61
61
|
|
62
62
|
[pagy, called.empty? ? response : response.send(*called)]
|
63
63
|
end
|
@@ -4,6 +4,8 @@
|
|
4
4
|
require 'pagy/extras/shared'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
7
9
|
module FoundationExtra
|
8
10
|
# Pagination for Foundation: it returns the html with the series of links to the pages
|
9
11
|
def pagy_foundation_nav(pagy, pagy_id: nil, link_extra: '')
|
@@ -17,6 +19,7 @@ class Pagy
|
|
17
19
|
when Integer then %(<li>#{link.call item}</li>) # page link
|
18
20
|
when String then %(<li class="current">#{item}</li>) # active page
|
19
21
|
when :gap then %(<li class="ellipsis gap" aria-hidden="true"></li>) # page gap
|
22
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
20
23
|
end
|
21
24
|
end
|
22
25
|
html << pagy_foundation_next_html(pagy, link)
|
data/lib/pagy/extras/gearbox.rb
CHANGED
@@ -13,7 +13,7 @@ class Pagy
|
|
13
13
|
return super if !@vars[:gearbox_extra] || @vars[:items_extra]
|
14
14
|
|
15
15
|
gearbox_items = @vars[:gearbox_items]
|
16
|
-
raise VariableError.new(self
|
16
|
+
raise VariableError.new(self, :gearbox_items, 'to be an Array of positives', gearbox_items) \
|
17
17
|
unless gearbox_items.is_a?(Array) && gearbox_items.all? { |num| num.positive? rescue false } # rubocop:disable Style/RescueModifier
|
18
18
|
|
19
19
|
@items = gearbox_items[@page - 1] || gearbox_items.last
|
data/lib/pagy/extras/items.rb
CHANGED
@@ -14,9 +14,9 @@ class Pagy # Default variables for this extra
|
|
14
14
|
|
15
15
|
# Set the items variable considering the params and other pagy variables
|
16
16
|
def pagy_set_items_from_params(vars)
|
17
|
-
return if vars[:items]
|
18
|
-
return unless vars.key?(:items_extra) ? vars[:items_extra] : DEFAULT[:items_extra]
|
19
|
-
return unless (items = params[vars[:items_param] || DEFAULT[:items_param]])
|
17
|
+
return if vars[:items] # :items explicitly set
|
18
|
+
return unless vars.key?(:items_extra) ? vars[:items_extra] : DEFAULT[:items_extra] # :items_extra is false
|
19
|
+
return unless (items = params[vars[:items_param] || DEFAULT[:items_param]]) # no items from request params
|
20
20
|
|
21
21
|
vars[:items] = [items.to_i, vars.key?(:max_items) ? vars[:max_items] : DEFAULT[:max_items]].compact.min
|
22
22
|
end
|
@@ -4,6 +4,8 @@
|
|
4
4
|
require 'pagy/extras/shared'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
7
9
|
module MaterializeExtra
|
8
10
|
# Pagination for materialize: it returns the html with the series of links to the pages
|
9
11
|
def pagy_materialize_nav(pagy, pagy_id: nil, link_extra: '')
|
@@ -17,6 +19,7 @@ class Pagy
|
|
17
19
|
when Integer then %(<li class="waves-effect">#{link.call item}</li>) # page link
|
18
20
|
when String then %(<li class="active">#{link.call item}</li>) # active page
|
19
21
|
when :gap then %(<li class="gap disabled"><a href="#">#{pagy_t 'pagy.nav.gap'}</a></li>) # page gap
|
22
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
20
23
|
end
|
21
24
|
end
|
22
25
|
html << pagy_materialize_next_html(pagy, link)
|
@@ -39,13 +39,13 @@ class Pagy
|
|
39
39
|
pagy = ::Pagy.new(vars)
|
40
40
|
# with :last_page overflow we need to re-run the method in order to get the hits
|
41
41
|
return pagy_meilisearch(pagy_search_args, vars.merge(page: pagy.page)) \
|
42
|
-
|
42
|
+
if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
|
43
43
|
|
44
44
|
[pagy, results]
|
45
45
|
end
|
46
46
|
|
47
|
-
# Sub-method called only by #pagy_meilisearch: here for easy customization of variables by overriding
|
48
|
-
#
|
47
|
+
# Sub-method called only by #pagy_meilisearch: here for easy customization of variables by overriding.
|
48
|
+
# The _collection argument is not available when the method is called.
|
49
49
|
def pagy_meilisearch_get_vars(_collection, vars)
|
50
50
|
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
51
51
|
vars[:items] ||= DEFAULT[:items]
|
data/lib/pagy/extras/metadata.rb
CHANGED
@@ -4,44 +4,20 @@
|
|
4
4
|
require 'pagy/url_helpers'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
DEFAULT[:metadata] = %i[ scaffold_url first_url prev_url page_url next_url last_url
|
8
|
+
count page items vars pages last in from to prev next series ]
|
9
|
+
|
7
10
|
# Add a specialized backend method for pagination metadata
|
8
11
|
module MetadataExtra
|
9
12
|
private
|
10
13
|
|
11
|
-
# Store the array of all the internal variable names usable as METADATA
|
12
|
-
METADATA = %i[ scaffold_url
|
13
|
-
first_url
|
14
|
-
prev_url
|
15
|
-
page_url
|
16
|
-
next_url
|
17
|
-
last_url
|
18
|
-
count page
|
19
|
-
items
|
20
|
-
vars
|
21
|
-
pages
|
22
|
-
last
|
23
|
-
in
|
24
|
-
from
|
25
|
-
to
|
26
|
-
prev
|
27
|
-
next
|
28
|
-
series ].tap { |m| m << :sequels if DEFAULT.key?(:steps) }.freeze
|
29
|
-
|
30
|
-
# Set the default metadata variable
|
31
|
-
Pagy::DEFAULT[:metadata] = METADATA.dup
|
32
|
-
|
33
14
|
include UrlHelpers
|
34
15
|
|
35
16
|
# Return the metadata hash
|
36
17
|
def pagy_metadata(pagy, absolute: nil)
|
37
|
-
names = pagy.vars[:metadata]
|
38
|
-
unknown = names - METADATA
|
39
|
-
raise VariableError.new(pagy), "expected :metadata to be in #{DEFAULT[:metadata].inspect}, got #{unknown.inspect} unknown" \
|
40
|
-
unless unknown.empty?
|
41
|
-
|
42
18
|
scaffold_url = pagy_url_for(pagy, PAGE_PLACEHOLDER, absolute: absolute)
|
43
19
|
{}.tap do |metadata|
|
44
|
-
|
20
|
+
pagy.vars[:metadata].each do |key|
|
45
21
|
metadata[key] = case key
|
46
22
|
when :scaffold_url then scaffold_url
|
47
23
|
when :first_url then scaffold_url.sub(PAGE_PLACEHOLDER, 1.to_s)
|
@@ -51,6 +27,8 @@ class Pagy
|
|
51
27
|
when :last_url then scaffold_url.sub(PAGE_PLACEHOLDER, pagy.last.to_s)
|
52
28
|
else pagy.send(key)
|
53
29
|
end
|
30
|
+
rescue NoMethodError
|
31
|
+
raise VariableError.new(pagy, :metadata, 'to contain known keys', key)
|
54
32
|
end
|
55
33
|
end
|
56
34
|
end
|
data/lib/pagy/extras/navs.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
require 'pagy/extras/shared'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
7
9
|
module NavsExtra
|
8
10
|
# Javascript pagination: it returns a nav and a JSON tag used by the Pagy.nav javascript
|
9
11
|
def pagy_nav_js(pagy, pagy_id: nil, link_extra: '', steps: nil)
|
data/lib/pagy/extras/overflow.rb
CHANGED
@@ -31,11 +31,11 @@ class Pagy
|
|
31
31
|
@prev = @last # prev relative to the actual page
|
32
32
|
extend Series # special series for :empty_page
|
33
33
|
else
|
34
|
-
raise VariableError.new(self
|
35
|
-
"expected :overflow to be in [:last_page, :empty_page, :exception]; got #{@vars[:overflow].inspect}"
|
34
|
+
raise VariableError.new(self, :overflow, 'to be in [:last_page, :empty_page, :exception]', @vars[:overflow])
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
38
|
+
# Special series for empty page
|
39
39
|
module Series
|
40
40
|
def series(size = @vars[:size])
|
41
41
|
@page = @last # series for last page
|
@@ -63,8 +63,7 @@ class Pagy
|
|
63
63
|
@vars[:size] = [] # no page in the series
|
64
64
|
self
|
65
65
|
else
|
66
|
-
raise VariableError.new(self
|
67
|
-
"expected :overflow to be in [:empty_page, :exception]; got #{@vars[:overflow].inspect}"
|
66
|
+
raise VariableError.new(self, :overflow, 'to be in [:empty_page, :exception]', @vars[:overflow])
|
68
67
|
end
|
69
68
|
end
|
70
69
|
end
|
@@ -7,8 +7,8 @@ class Pagy
|
|
7
7
|
module SearchkickExtra
|
8
8
|
module Searchkick
|
9
9
|
# Return an array used to delay the call of #search
|
10
|
-
# after the pagination variables are merged to the options
|
11
|
-
#
|
10
|
+
# after the pagination variables are merged to the options.
|
11
|
+
# It also pushes to the same array an optional method call.
|
12
12
|
def pagy_searchkick(term = '*', **options, &block)
|
13
13
|
[self, term, options, block].tap do |args|
|
14
14
|
args.define_singleton_method(:method_missing) { |*a| args += a }
|
@@ -44,7 +44,7 @@ class Pagy
|
|
44
44
|
pagy = ::Pagy.new(vars)
|
45
45
|
# with :last_page overflow we need to re-run the method in order to get the hits
|
46
46
|
return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page)) \
|
47
|
-
|
47
|
+
if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
|
48
48
|
|
49
49
|
[pagy, called.empty? ? results : results.send(*called)]
|
50
50
|
end
|
data/lib/pagy/extras/semantic.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
require 'pagy/extras/shared'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
7
9
|
module SemanticExtra
|
8
10
|
# Pagination for semantic: it returns the html with the series of links to the pages
|
9
11
|
def pagy_semantic_nav(pagy, pagy_id: nil, link_extra: '')
|
@@ -17,6 +19,7 @@ class Pagy
|
|
17
19
|
when Integer then link.call item # page link
|
18
20
|
when String then %(<a class="item active">#{item}</a>) # current page
|
19
21
|
when :gap then %(<div class="disabled item">#{pagy_t 'pagy.nav.gap'}</div>) # page gap
|
22
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
20
23
|
end
|
21
24
|
end
|
22
25
|
html << pagy_semantic_next_html(pagy, link)
|
data/lib/pagy/extras/shared.rb
CHANGED
@@ -19,8 +19,7 @@ class Pagy
|
|
19
19
|
# Notice: if :steps is false it will use the single {0 => @vars[:size]} size
|
20
20
|
def sequels(steps = nil)
|
21
21
|
steps ||= @vars[:steps] || { 0 => @vars[:size] }
|
22
|
-
raise VariableError.new(self
|
23
|
-
unless steps.key?(0)
|
22
|
+
raise VariableError.new(self, :steps, 'to define the 0 width', steps) unless steps.key?(0)
|
24
23
|
|
25
24
|
{}.tap do |sequels|
|
26
25
|
steps.each { |width, size| sequels[width.to_s] = series(size) }
|
@@ -31,14 +30,14 @@ class Pagy
|
|
31
30
|
# Additions for the Frontend
|
32
31
|
module Frontend
|
33
32
|
if defined?(Oj)
|
34
|
-
#
|
33
|
+
# Return a script tag with the JSON-serialized args generated with the faster oj gem
|
35
34
|
def pagy_json_attr(pagy, *args)
|
36
35
|
args << pagy.vars[:page_param] if pagy.vars[:trim_extra]
|
37
36
|
%(data-pagy-json="#{Oj.dump(args, mode: :strict).gsub('"', '"')}")
|
38
37
|
end
|
39
38
|
else
|
40
39
|
require 'json'
|
41
|
-
#
|
40
|
+
# Return a script tag with the JSON-serialized args generated with the slower to_json
|
42
41
|
def pagy_json_attr(pagy, *args)
|
43
42
|
args << pagy.vars[:page_param] if pagy.vars[:trim_extra]
|
44
43
|
%(data-pagy-json="#{args.to_json.gsub('"', '"')}")
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
require 'uri'
|
5
5
|
class Pagy
|
6
|
+
# Use pagy without any request object, nor Rack environment/gem, nor any defined params method,
|
7
|
+
# even in the irb/rails console without any app or config.
|
6
8
|
module StandaloneExtra
|
7
9
|
# Extracted from Rack::Utils and reformatted for rubocop
|
8
10
|
module QueryUtils
|
@@ -30,21 +32,22 @@ class Pagy
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
#
|
34
|
-
#
|
35
|
+
# Return the URL for the page. If there is no pagy.vars[:url]
|
36
|
+
# it works exactly as the regular #pagy_url_for, relying on the params method and Rack.
|
37
|
+
# If there is a defined pagy.vars[:url] variable it does not need the params method nor Rack.
|
35
38
|
def pagy_url_for(pagy, page, absolute: nil)
|
36
|
-
|
37
|
-
return super unless (url =
|
38
|
-
|
39
|
-
params
|
40
|
-
params[
|
41
|
-
params[
|
42
|
-
|
43
|
-
query_string = "?#{QueryUtils.build_nested_query(pagy_massage_params(params))}"
|
44
|
-
"#{url}#{query_string}#{
|
39
|
+
vars = pagy.vars
|
40
|
+
return super unless (url = vars[:url])
|
41
|
+
|
42
|
+
params = vars[:params].clone # safe when it gets reused
|
43
|
+
params[vars[:page_param]] = page
|
44
|
+
params[vars[:items_param]] = vars[:items] if vars[:items_extra]
|
45
|
+
|
46
|
+
query_string = "?#{QueryUtils.build_nested_query(pagy_massage_params(params))}"
|
47
|
+
"#{url}#{query_string}#{vars[:fragment]}"
|
45
48
|
end
|
46
49
|
end
|
47
|
-
# In ruby 3+
|
50
|
+
# In ruby 3+ `UrlHelpers.prepend StandaloneExtra` would be enough instead of using the next 2 lines
|
48
51
|
Frontend.prepend StandaloneExtra
|
49
52
|
Backend.prepend StandaloneExtra
|
50
53
|
|
data/lib/pagy/extras/support.rb
CHANGED
@@ -3,14 +3,17 @@
|
|
3
3
|
|
4
4
|
class Pagy
|
5
5
|
module SupportExtra
|
6
|
+
# Return the previous page URL string or nil
|
6
7
|
def pagy_prev_url(pagy)
|
7
8
|
pagy_url_for(pagy, pagy.prev) if pagy.prev
|
8
9
|
end
|
9
10
|
|
11
|
+
# Return the next page URL string or nil
|
10
12
|
def pagy_next_url(pagy)
|
11
13
|
pagy_url_for(pagy, pagy.next) if pagy.next
|
12
14
|
end
|
13
15
|
|
16
|
+
# Return the HTML string for the previous page link
|
14
17
|
def pagy_prev_link(pagy, text: pagy_t('pagy.nav.prev'), link_extra: '')
|
15
18
|
if pagy.prev
|
16
19
|
%(<span class="page prev"><a href="#{
|
@@ -23,6 +26,7 @@ class Pagy
|
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
29
|
+
# Return the HTML string for the next page link
|
26
30
|
def pagy_next_link(pagy, text: pagy_t('pagy.nav.next'), link_extra: '')
|
27
31
|
if pagy.next
|
28
32
|
%(<span class="page next"><a href="#{
|
@@ -35,10 +39,12 @@ class Pagy
|
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
42
|
+
# Return the HTML link tag for the previous page or nil
|
38
43
|
def pagy_prev_link_tag(pagy)
|
39
44
|
%(<link href="#{pagy_url_for(pagy, pagy.prev)}" rel="prev"/>) if pagy.prev
|
40
45
|
end
|
41
46
|
|
47
|
+
# Return the HTML link tag for the next page or nil
|
42
48
|
def pagy_next_link_tag(pagy)
|
43
49
|
%(<link href="#{pagy_url_for(pagy, pagy.next)}" rel="next"/>) if pagy.next
|
44
50
|
end
|
data/lib/pagy/extras/trim.rb
CHANGED
@@ -5,7 +5,8 @@ class Pagy
|
|
5
5
|
DEFAULT[:trim_extra] = true # extra enabled by default
|
6
6
|
|
7
7
|
module TrimExtra
|
8
|
-
# Override the original
|
8
|
+
# Override the original pagy_link_proc.
|
9
|
+
# Call the pagy_trim method if the trim_extra is enabled.
|
9
10
|
def pagy_link_proc(pagy, link_extra: '')
|
10
11
|
link_proc = super(pagy, link_extra: link_extra)
|
11
12
|
return link_proc unless pagy.vars[:trim_extra]
|
data/lib/pagy/extras/uikit.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
require 'pagy/extras/shared'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
7
9
|
module UikitExtra
|
8
10
|
# Pagination for uikit: it returns the html with the series of links to the pages
|
9
11
|
def pagy_uikit_nav(pagy, pagy_id: nil, link_extra: '')
|
@@ -16,6 +18,7 @@ class Pagy
|
|
16
18
|
when Integer then %(<li>#{link.call item}</li>)
|
17
19
|
when String then %(<li class="uk-active"><span>#{item}</span></li>)
|
18
20
|
when :gap then %(<li class="uk-disabled"><span>#{pagy_t 'pagy.nav.gap'}</span></li>)
|
21
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
19
22
|
end
|
20
23
|
end
|
21
24
|
html << pagy_uikit_next_html(pagy, link)
|
data/lib/pagy/frontend.rb
CHANGED
@@ -8,8 +8,8 @@ class Pagy
|
|
8
8
|
# Used for search and replace, hardcoded also in the pagy.js file
|
9
9
|
PAGE_PLACEHOLDER = '__pagy_page__'
|
10
10
|
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# Frontend modules are specially optimized for performance.
|
12
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
13
13
|
module Frontend
|
14
14
|
include UrlHelpers
|
15
15
|
|
@@ -31,6 +31,7 @@ class Pagy
|
|
31
31
|
when Integer then %(<span class="page">#{link.call item}</span> ) # page link
|
32
32
|
when String then %(<span class="page active">#{item}</span> ) # current page
|
33
33
|
when :gap then %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> ) # page gap
|
34
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
34
35
|
end
|
35
36
|
end
|
36
37
|
html << if p_next
|
data/lib/pagy/i18n.rb
CHANGED
@@ -10,7 +10,7 @@ class Pagy
|
|
10
10
|
|
11
11
|
# Pluralization rules
|
12
12
|
module P11n
|
13
|
-
#
|
13
|
+
# Utility variables
|
14
14
|
from0to1 = [0, 1].freeze
|
15
15
|
from2to4 = [2, 3, 4].freeze
|
16
16
|
from5to9 = [5, 6, 7, 8, 9].freeze
|
@@ -130,7 +130,7 @@ class Pagy
|
|
130
130
|
locale[:filepath] ||= Pagy.root.join('locales', "#{locale[:locale]}.yml")
|
131
131
|
locale[:pluralize] ||= P11n::LOCALE[locale[:locale]]
|
132
132
|
dictionary = YAML.safe_load(File.read(locale[:filepath], encoding: 'UTF-8'))
|
133
|
-
raise
|
133
|
+
raise I18nError, %(expected :locale "#{locale[:locale]}" not found in :filepath "#{locale[:filepath].inspect}") \
|
134
134
|
unless dictionary.key?(locale[:locale])
|
135
135
|
|
136
136
|
DATA[locale[:locale]] = [flatten(dictionary[locale[:locale]]), locale[:pluralize]]
|
data/lib/pagy/url_helpers.rb
CHANGED
@@ -3,15 +3,17 @@
|
|
3
3
|
class Pagy
|
4
4
|
# Provide the helpers to handle the url in frontend and backend
|
5
5
|
module UrlHelpers
|
6
|
-
#
|
6
|
+
# Return the URL for the page, relying on the params method and Rack by default.
|
7
|
+
# It supports all Rack-based frameworks (Sinatra, Padrino, Rails, ...).
|
8
|
+
# For non-rack environments you can use the standalone extra
|
7
9
|
def pagy_url_for(pagy, page, absolute: nil)
|
8
|
-
|
9
|
-
params
|
10
|
-
params[
|
11
|
-
params[
|
12
|
-
|
13
|
-
query_string = "?#{Rack::Utils.build_nested_query(pagy_massage_params(params))}"
|
14
|
-
"#{request.base_url if absolute}#{request.path}#{query_string}#{
|
10
|
+
vars = pagy.vars
|
11
|
+
params = request.params.merge(vars[:params].transform_keys(&:to_s))
|
12
|
+
params[vars[:page_param].to_s] = page
|
13
|
+
params[vars[:items_param].to_s] = vars[:items] if vars[:items_extra]
|
14
|
+
|
15
|
+
query_string = "?#{Rack::Utils.build_nested_query(pagy_massage_params(params))}"
|
16
|
+
"#{request.base_url if absolute}#{request.path}#{query_string}#{vars[:fragment]}"
|
15
17
|
end
|
16
18
|
|
17
19
|
# Sub-method called only by #pagy_url_for: here for easy customization of params by overriding
|
data/lib/pagy.rb
CHANGED
@@ -5,7 +5,7 @@ require 'pathname'
|
|
5
5
|
|
6
6
|
# Core class
|
7
7
|
class Pagy
|
8
|
-
VERSION = '5.
|
8
|
+
VERSION = '5.1.2'
|
9
9
|
|
10
10
|
# Root pathname to get the path of Pagy files like templates or dictionaries
|
11
11
|
def self.root
|
@@ -32,8 +32,7 @@ class Pagy
|
|
32
32
|
setup_vars(count: 0, page: 1, outset: 0)
|
33
33
|
setup_items_var
|
34
34
|
setup_pages_var
|
35
|
-
raise OverflowError.new(self
|
36
|
-
if @page > @last
|
35
|
+
raise OverflowError.new(self, :page, "in 1..#{@last}", @page) if @page > @last
|
37
36
|
|
38
37
|
@offset = (@items * (@page - 1)) + @outset
|
39
38
|
@from = [@offset - @outset + 1, @count].min
|
@@ -46,7 +45,7 @@ class Pagy
|
|
46
45
|
# Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
47
46
|
def series(size = @vars[:size])
|
48
47
|
return [] if size.empty?
|
49
|
-
raise VariableError.new(self
|
48
|
+
raise VariableError.new(self, :size, 'to contain 4 items >= 0', size) \
|
50
49
|
unless size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
|
51
50
|
|
52
51
|
# This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
|
@@ -81,7 +80,7 @@ class Pagy
|
|
81
80
|
# Setup and validates the passed vars: var must be present and value.to_i must be >= to min
|
82
81
|
def setup_vars(name_min)
|
83
82
|
name_min.each do |name, min|
|
84
|
-
raise VariableError.new(self
|
83
|
+
raise VariableError.new(self, name, ">= #{min}", @vars[name]) \
|
85
84
|
unless @vars[name] && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
|
86
85
|
end
|
87
86
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pagy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Domizio Demichelis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Agnostic pagination in plain ruby. It does it all. Better.
|
14
14
|
email:
|