pagy 4.10.1 → 5.0.1

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/config/pagy.rb +69 -44
  3. data/lib/javascripts/pagy.js +17 -4
  4. data/lib/pagy/backend.rb +6 -10
  5. data/lib/pagy/console.rb +5 -4
  6. data/lib/pagy/countless.rb +18 -20
  7. data/lib/pagy/exceptions.rb +15 -16
  8. data/lib/pagy/extras/arel.rb +6 -6
  9. data/lib/pagy/extras/array.rb +6 -6
  10. data/lib/pagy/extras/bootstrap.rb +33 -29
  11. data/lib/pagy/extras/bulma.rb +41 -32
  12. data/lib/pagy/extras/countless.rb +10 -7
  13. data/lib/pagy/extras/elasticsearch_rails.rb +64 -47
  14. data/lib/pagy/extras/foundation.rb +27 -26
  15. data/lib/pagy/extras/gearbox.rb +42 -0
  16. data/lib/pagy/extras/headers.rb +24 -16
  17. data/lib/pagy/extras/i18n.rb +7 -16
  18. data/lib/pagy/extras/items.rb +37 -38
  19. data/lib/pagy/extras/materialize.rb +29 -30
  20. data/lib/pagy/extras/meilisearch.rb +50 -45
  21. data/lib/pagy/extras/metadata.rb +14 -20
  22. data/lib/pagy/extras/navs.rb +24 -26
  23. data/lib/pagy/extras/overflow.rb +55 -60
  24. data/lib/pagy/extras/searchkick.rb +51 -45
  25. data/lib/pagy/extras/semantic.rb +29 -30
  26. data/lib/pagy/extras/shared.rb +43 -40
  27. data/lib/pagy/extras/standalone.rb +37 -42
  28. data/lib/pagy/extras/support.rb +14 -13
  29. data/lib/pagy/extras/trim.rb +14 -11
  30. data/lib/pagy/extras/uikit.rb +28 -28
  31. data/lib/pagy/frontend.rb +23 -47
  32. data/lib/pagy/i18n.rb +159 -0
  33. data/lib/pagy/url_helpers.rb +22 -0
  34. data/lib/pagy.rb +54 -29
  35. data/lib/templates/uikit_nav.html.erb +1 -1
  36. data/lib/templates/uikit_nav.html.slim +1 -1
  37. metadata +8 -11
  38. data/lib/locales/utils/i18n.rb +0 -17
  39. data/lib/locales/utils/loader.rb +0 -31
  40. data/lib/locales/utils/p11n.rb +0 -112
  41. data/lib/pagy/deprecation.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfababb2b5f9594ebcf7827cde7c45e9073ba9a270ddca251714e0d8fa1ef711
4
- data.tar.gz: b20c84d4099a7302d6324fa671001051275d01d363eff5b6007d4240b1700d8a
3
+ metadata.gz: a1345a70a6c730b386f155905f1f64821d0843704a378906cec76a27a68f77bc
4
+ data.tar.gz: b067a51f4178b84cf164374382b41e061e4d0e257819961abb2ef8d3e516c83d
5
5
  SHA512:
6
- metadata.gz: ba6eadeb0285c6dcf1ae98dfe58fe8844916f3d517813fbc8add6b5b0e0d3933234e26eb15c9fa931c7fccd256844df26d72694f23a3596fa874c3288a4fd4aa
7
- data.tar.gz: 35d1b022f3d4c85521e69b960be16812c5ffe276e1a015e6fa9ce1630f1abf05486908568585dcd0257fee4d2fb304fe6296839404a9091e54a3c6fa10d0068b
6
+ metadata.gz: 8aa6a995fff4c56eade45efb978ad63beb36f2ee10152dbf89365cf18d66911f89a7f84f36b35ce94b4228a286f18b6343a6c30c80434bd9ad6a12c177b47b3e
7
+ data.tar.gz: 4a9288306aff02bfc789a3198f38c02ed6b7d038d2caddf1eba1d3b4102e4f1f61c111eefd60c126c6a4f5c2e3b88dd745802732324d506bed8bbd118361027f
data/lib/config/pagy.rb CHANGED
@@ -1,32 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Pagy initializer file (4.10.1)
3
+ # Pagy initializer file (5.0.1)
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
 
7
7
 
8
8
  # Pagy Variables
9
9
  # See https://ddnexus.github.io/pagy/api/pagy#variables
10
- # All the Pagy::VARS are set for all the Pagy instances but can be overridden
10
+ # All the Pagy::DEFAULT are set for all the Pagy instances but can be overridden
11
11
  # per instance by just passing them to Pagy.new or the #pagy controller method
12
12
 
13
13
 
14
14
  # Instance variables
15
15
  # See https://ddnexus.github.io/pagy/api/pagy#instance-variables
16
- # Pagy::VARS[:page] = 1 # default
17
- # Pagy::VARS[:items] = 20 # default
18
- # Pagy::VARS[:outset] = 0 # default
16
+ # Pagy::DEFAULT[:page] = 1 # default
17
+ # Pagy::DEFAULT[:items] = 20 # default
18
+ # Pagy::DEFAULT[:outset] = 0 # default
19
19
 
20
20
 
21
21
  # Other Variables
22
22
  # See https://ddnexus.github.io/pagy/api/pagy#other-variables
23
- # Pagy::VARS[:size] = [1,4,4,1] # default
24
- # Pagy::VARS[:page_param] = :page # default
25
- # Pagy::VARS[:params] = {} # default
26
- # Pagy::VARS[:fragment] = '#fragment' # example
27
- # Pagy::VARS[:link_extra] = 'data-remote="true"' # example
28
- # Pagy::VARS[:i18n_key] = 'pagy.item_name' # default
29
- # Pagy::VARS[:cycle] = true # example
23
+ # Pagy::DEFAULT[:size] = [1,4,4,1] # default
24
+ # Pagy::DEFAULT[:page_param] = :page # default
25
+ # Pagy::DEFAULT[:params] = {} # default
26
+ # Pagy::DEFAULT[:fragment] = '#fragment' # example
27
+ # Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example
28
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
29
+ # Pagy::DEFAULT[:cycle] = true # example
30
30
 
31
31
 
32
32
  # Extras
@@ -42,20 +42,47 @@
42
42
  # Countless extra: Paginate without any count, saving one query per rendering
43
43
  # See https://ddnexus.github.io/pagy/extras/countless
44
44
  # require 'pagy/extras/countless'
45
+ # Pagy::DEFAULT[:countless_minimal] = false # default (eager loading)
45
46
 
46
47
  # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
47
48
  # See https://ddnexus.github.io/pagy/extras/elasticsearch_rails
48
- # default :pagy_search method: change only if you use
49
- # also the searchkick extra that defines the same
50
- # VARS[:elasticsearch_rails_search_method] = :pagy_search
49
+ # default :pagy_search method: change only if you use also
50
+ # the searchkick or meilisearch extra that defines the same
51
+ # Pagy::DEFAULT[:elasticsearch_rails_search_method] = :pagy_search
51
52
  # require 'pagy/extras/elasticsearch_rails'
52
53
 
54
+ # Headers extra: http response headers (and other helpers) useful for API pagination
55
+ # See http://ddnexus.github.io/pagy/extras/headers
56
+ # require 'pagy/extras/headers'
57
+ # Pagy::DEFAULT[:headers] = { page: 'Current-Page',
58
+ # items: 'Page-Items',
59
+ # count: 'Total-Count',
60
+ # pages: 'Total-Pages' } # default
61
+
62
+ # Meilisearch extra: Paginate `Meilisearch` result objects
63
+ # See https://ddnexus.github.io/pagy/extras/meilisearch
64
+ # default :pagy_search method: change only if you use also
65
+ # the elasticsearch_rails or searchkick extra that define the same method
66
+ # Pagy::DEFAULT[:meilisearch_search_method] = :pagy_search
67
+ # require 'pagy/extras/meilisearch'
68
+
69
+ # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
70
+ # See https://ddnexus.github.io/pagy/extras/metadata
71
+ # you must require the shared internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
72
+ # require 'pagy/extras/shared'
73
+ # require 'pagy/extras/metadata'
74
+ # For performance reason, you should explicitly set ONLY the metadata you use in the frontend
75
+ # Pagy::DEFAULT[:metadata] = [:scaffold_url, :count, :page, :prev, :next, :last] # example
76
+
53
77
  # Searchkick extra: Paginate `Searchkick::Results` objects
54
78
  # See https://ddnexus.github.io/pagy/extras/searchkick
55
- # default :pagy_search method: change only if you use
56
- # also the elasticsearch_rails extra that defines the same
57
- # VARS[:searchkick_search_method] = :pagy_search
79
+ # default :pagy_search method: change only if you use also
80
+ # the elasticsearch_rails or meilisearch extra that defines the same
81
+ # DEFAULT[:searchkick_search_method] = :pagy_search
58
82
  # require 'pagy/extras/searchkick'
83
+ # uncomment if you are going to use Searchkick.pagy_search
84
+ # Searchkick.extend Pagy::Searchkick
85
+
59
86
 
60
87
  # Frontend Extras
61
88
 
@@ -91,47 +118,40 @@
91
118
 
92
119
  # Multi size var used by the *_nav_js helpers
93
120
  # See https://ddnexus.github.io/pagy/extras/navs#steps
94
- # Pagy::VARS[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example
121
+ # Pagy::DEFAULT[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example
95
122
 
96
123
 
97
124
  # Feature Extras
98
125
 
99
- # Headers extra: http response headers (and other helpers) useful for API pagination
100
- # See http://ddnexus.github.io/pagy/extras/headers
101
- # require 'pagy/extras/headers'
102
- # Pagy::VARS[:headers] = { page: 'Current-Page', items: 'Page-Items', count: 'Total-Count', pages: 'Total-Pages' } # default
103
-
104
- # Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
105
- # See https://ddnexus.github.io/pagy/extras/support
106
- # require 'pagy/extras/support'
126
+ # Gearbox extra: Automatically change the number of items per page depending on the page number
127
+ # See https://ddnexus.github.io/pagy/extras/gearbox
128
+ # require 'pagy/extras/gearbox'
129
+ # set to false only if you want to make :gearbox_extra an opt-in variable
130
+ # Pagy::DEFAULT[:gearbox_extra] = false # default true
131
+ # Pagy::DEFAULT[:gearbox_items] = [15, 30, 60, 100] # default
107
132
 
108
133
  # Items extra: Allow the client to request a custom number of items per page with an optional selector UI
109
134
  # See https://ddnexus.github.io/pagy/extras/items
110
135
  # require 'pagy/extras/items'
111
- # Pagy::VARS[:items_param] = :items # default
112
- # Pagy::VARS[:max_items] = 100 # default
113
- # set to false if you want to make :enable_items_extra an opt-in variable
114
- # Pagy::VARS[:enable_items_extra] = false # default true
136
+ # set to false only if you want to make :items_extra an opt-in variable
137
+ # Pagy::DEFAULT[:items_extra] = false # default true
138
+ # Pagy::DEFAULT[:items_param] = :items # default
139
+ # Pagy::DEFAULT[:max_items] = 100 # default
115
140
 
116
141
  # Overflow extra: Allow for easy handling of overflowing pages
117
142
  # See https://ddnexus.github.io/pagy/extras/overflow
118
143
  # require 'pagy/extras/overflow'
119
- # Pagy::VARS[:overflow] = :empty_page # default (other options: :last_page and :exception)
144
+ # Pagy::DEFAULT[:overflow] = :empty_page # default (other options: :last_page and :exception)
120
145
 
121
- # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
122
- # See https://ddnexus.github.io/pagy/extras/metadata
123
- # you must require the shared internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
124
- # require 'pagy/extras/shared'
125
- # require 'pagy/extras/metadata'
126
- # For performance reason, you should explicitly set ONLY the metadata you use in the frontend
127
- # Pagy::VARS[:metadata] = [:scaffold_url, :count, :page, :prev, :next, :last] # example
146
+ # Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
147
+ # See https://ddnexus.github.io/pagy/extras/support
148
+ # require 'pagy/extras/support'
128
149
 
129
150
  # Trim extra: Remove the page=1 param from links
130
151
  # See https://ddnexus.github.io/pagy/extras/trim
131
152
  # require 'pagy/extras/trim'
132
- # after requiring it will trim by default
133
- # set to false if you want to make :enable_trim_extra an opt-in variable
134
- # Pagy::VARS[:enable_trim_extra] = false # default true
153
+ # set to false only if you want to make :trim_extra an opt-in variable
154
+ # Pagy::DEFAULT[:trim_extra] = false # default true
135
155
 
136
156
 
137
157
  # Rails
@@ -169,7 +189,7 @@
169
189
  # {locale: 'es', filepath: 'path/to/pagy-es.yml'},
170
190
  # {locale: 'xyz', # not built-in
171
191
  # filepath: 'path/to/pagy-xyz.yml',
172
- # pluralize: lambda{|count| ... } )
192
+ # pluralize: lambda{ |count| ... } )
173
193
 
174
194
 
175
195
  # I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory
@@ -178,4 +198,9 @@
178
198
  # require 'pagy/extras/i18n'
179
199
 
180
200
  # Default i18n key
181
- # Pagy::VARS[:i18n_key] = 'pagy.item_name' # default
201
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
202
+
203
+
204
+ # When you are done setting your own defaults freeze it,
205
+ # so it will not changed accidentally
206
+ Pagy::DEFAULT.freeze
@@ -1,11 +1,14 @@
1
1
  // See the Pagy documentation: https://ddnexus.github.io/pagy/extras#javascript
2
2
 
3
+ // Container of the whole pagy stuff
3
4
  function Pagy(){}
4
5
 
5
- Pagy.version = '4.10.1'
6
+ Pagy.version = '5.0.1'
6
7
 
8
+ // Used by the waitForMe function
7
9
  Pagy.delay = 100
8
10
 
11
+ // Scan the target for data-pagy-json elements and apply their functions
9
12
  Pagy.init =
10
13
  function(arg) {
11
14
  var target = arg instanceof Event || arg === undefined ? document : arg,
@@ -18,6 +21,7 @@ Pagy.init =
18
21
  }
19
22
  }
20
23
 
24
+ // Power the pagy*_nav_js helpers
21
25
  Pagy.nav =
22
26
  function(pagyEl, tags, sequels, trimParam) {
23
27
  var lastWidth,
@@ -45,14 +49,14 @@ Pagy.nav =
45
49
  else if (typeof(item) === 'string') { html += tags.active.replace(pageREg, item) }
46
50
  }
47
51
  html += tags.after
48
- this.innerHTML = ''
49
52
  this.insertAdjacentHTML('afterbegin', html)
50
53
  lastWidth = width
51
54
  }
52
55
  }.bind(pagyEl)
53
56
  pagyEl.render()
54
- }
57
+ }
55
58
 
59
+ // Power the pagy*_combo_nav_js helpers
56
60
  Pagy.combo_nav =
57
61
  function(pagyEl, page, link, trimParam) {
58
62
  var input = pagyEl.getElementsByTagName('input')[0],
@@ -68,6 +72,7 @@ Pagy.combo_nav =
68
72
  Pagy.addInputEventListeners(input, toPage)
69
73
  }
70
74
 
75
+ // Power the pagy_items_selector_js helper
71
76
  Pagy.items_selector =
72
77
  function(pagyEl, from, link, param) {
73
78
  var input = pagyEl.getElementsByTagName('input')[0],
@@ -75,6 +80,7 @@ Pagy.items_selector =
75
80
  toPage =
76
81
  function() {
77
82
  var items = input.value
83
+ if (items === 0 || items === '') { return }
78
84
  if (current !== items) {
79
85
  var page = Math.max(Math.ceil(from / items), 1),
80
86
  html = link.replace(/__pagy_page__/, page).replace(/__pagy_items__/, items)
@@ -86,6 +92,7 @@ Pagy.items_selector =
86
92
  Pagy.addInputEventListeners(input, toPage)
87
93
  }
88
94
 
95
+ // Utility for input fields
89
96
  Pagy.addInputEventListeners =
90
97
  function(input, toPage) {
91
98
  // select the content on click: easier for typing a number
@@ -96,22 +103,28 @@ Pagy.addInputEventListeners =
96
103
  input.addEventListener('keyup', function(e) { if (e.which === 13) {toPage()} }.bind(this))
97
104
  }
98
105
 
106
+ // Power the trim extra for js helpers
99
107
  Pagy.trim =
100
108
  function(html, param) {
101
109
  var re = new RegExp('[?&]' + param + '=1\\b(?!&)|\\b' + param + '=1&')
102
110
  return html.replace(re, '')
103
111
  }
104
112
 
113
+ // Render all *nav_js helpers
105
114
  Pagy.renderNavs =
106
115
  function() {
107
116
  var navs = document.getElementsByClassName('pagy-njs') // 'pagy-njs' is common to all *nav_js helpers
108
117
  for (var i = 0, len = navs.length; i < len; i++) { navs[i].render() }
109
118
  }
110
119
 
120
+ // Throttle to avoid to fire multiple time the renderNavs on resize
111
121
  Pagy.waitForMe =
112
122
  function() {
113
123
  if (typeof(Pagy.tid) === 'number') { clearTimeout(Pagy.tid) }
114
124
  Pagy.tid = setTimeout(Pagy.renderNavs, Pagy.delay)
115
125
  }
116
126
 
117
- window.addEventListener('resize', Pagy.waitForMe, true)
127
+ // If there is a window object then add the event listener on resize
128
+ if (typeof window !== 'undefined') {
129
+ window.addEventListener('resize', Pagy.waitForMe, true)
130
+ }
data/lib/pagy/backend.rb CHANGED
@@ -2,26 +2,23 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class Pagy
5
- # Defines a few generic methods to paginate an ORM collection out of the box,
5
+ # Define a few generic methods to paginate an ORM collection out of the box,
6
6
  # or any collection by overriding pagy_get_items and/or pagy_get_vars in your controller
7
-
8
7
  # See also the extras if you need specialized methods to paginate Arrays or other collections
9
-
10
-
11
8
  module Backend
12
- private # the whole module is private so no problem with including it in a controller
9
+ private
13
10
 
14
11
  # Return Pagy object and items
15
- def pagy(collection, vars={})
12
+ def pagy(collection, vars = {})
16
13
  pagy = Pagy.new(pagy_get_vars(collection, vars))
17
- [ pagy, pagy_get_items(collection, pagy) ]
14
+ [pagy, pagy_get_items(collection, pagy)]
18
15
  end
19
16
 
20
17
  # Sub-method called only by #pagy: here for easy customization of variables by overriding
21
18
  def pagy_get_vars(collection, vars)
22
- pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
19
+ pagy_set_items_from_params(vars) if defined?(ItemsExtra)
23
20
  vars[:count] ||= (c = collection.count(:all)).is_a?(Hash) ? c.size : c
24
- vars[:page] ||= params[ vars[:page_param] || VARS[:page_param] ]
21
+ vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
25
22
  vars
26
23
  end
27
24
 
@@ -30,6 +27,5 @@ class Pagy
30
27
  # This should work with ActiveRecord, Sequel, Mongoid...
31
28
  collection.offset(pagy.offset).limit(pagy.items)
32
29
  end
33
-
34
30
  end
35
31
  end
data/lib/pagy/console.rb CHANGED
@@ -1,21 +1,22 @@
1
+ # See Pagy::Console API documentation: https://ddnexus.github.io/pagy/api/console
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'pagy' # so you can require just the extra in the console
4
5
  require 'pagy/extras/standalone'
5
6
 
6
7
  class Pagy
7
- # include Pagy::Console in irb/rails console for a ready to use pagy environment
8
+ # Provide ready to use pagy environment when included in irb/rails console
8
9
  module Console
9
10
  def self.included(main)
10
11
  main.include(Backend)
11
12
  main.include(Frontend)
12
- VARS[:url] = 'http://www.example.com/subdir'
13
+ DEFAULT[:url] = 'http://www.example.com/subdir'
13
14
  end
14
15
 
16
+ # Require the extras passed as arguments
15
17
  def pagy_extras(*extras)
16
- extras.each {|extra| require "pagy/extras/#{extra}"}
18
+ extras.each { |extra| require "pagy/extras/#{extra}" }
17
19
  puts "Required extras: #{extras.map(&:inspect).join(', ')}"
18
20
  end
19
21
  end
20
-
21
22
  end
@@ -1,36 +1,34 @@
1
+ # See Pagy::Countless API documentation: https://ddnexus.github.io/pagy/api/countless
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'pagy'
4
5
 
5
6
  class Pagy
6
-
7
+ # No need to know the count to paginate
7
8
  class Countless < Pagy
8
-
9
- INSTANCE_VARS_MIN = { items: 1, page: 1, outset: 0 }.freeze
10
-
11
9
  # Merge and validate the options, do some simple arithmetic and set a few instance variables
12
- def initialize(vars={}) # rubocop:disable Lint/MissingSuper
13
- @vars = VARS.merge(vars.delete_if{|_,v| v.nil? || v == '' }) # default vars + cleaned vars (can be overridden)
14
- INSTANCE_VARS_MIN.each do |k,min| # validate instance variables
15
- raise VariableError.new(self), "expected :#{k} >= #{min}; got #{@vars[k].inspect}" \
16
- unless @vars[k] && instance_variable_set(:"@#{k}", @vars[k].to_i) >= min
17
- end
18
- @offset = @items * (@page - 1) + @outset # pagination offset + outset (initial offset)
10
+ def initialize(vars = {}) # rubocop:disable Lint/MissingSuper
11
+ normalize_vars(vars)
12
+ setup_vars(page: 1, outset: 0)
13
+ setup_items_var
14
+ @offset = (@items * (@page - 1)) + @outset
19
15
  end
20
16
 
21
17
  # Finalize the instance variables based on the fetched items
22
18
  def finalize(fetched)
23
- raise OverflowError.new(self), "page #{@page} got no items" \
24
- if fetched.zero? && @page > 1
25
-
26
- @pages = @last = (fetched > @items ? @page + 1 : @page) # set the @pages and @last
27
- @items = fetched if fetched < @items && fetched.positive? # adjust items for last non-empty page
28
- @from = fetched.zero? ? 0 : @offset + 1 - @outset # page begins from item
29
- @to = fetched.zero? ? 0 : @offset + @items - @outset # page ends to item
30
- @prev = (@page-1 unless @page == 1) # nil if no prev page
31
- @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1 # nil if no next page, 1 if :cycle
19
+ raise OverflowError.new(self, :page, "to be < #{@page}") if fetched.zero? && @page > 1
20
+
21
+ @pages = @last = (fetched > @items ? @page + 1 : @page)
22
+ @in = [fetched, @items].min
23
+ @from = @in.zero? ? 0 : @offset - @outset + 1
24
+ @to = @offset - @outset + @in
25
+ @prev = (@page - 1 unless @page == 1)
26
+ @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
32
27
  self
33
28
  end
34
29
 
30
+ def series(_size = @vars[:size])
31
+ super unless @vars[:countless_minimal]
32
+ end
35
33
  end
36
34
  end
@@ -1,27 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Pagy
4
-
5
- # generic variable error
4
+ # Generic variable error
6
5
  class VariableError < ArgumentError
7
- attr_reader :pagy
8
-
9
- def initialize(pagy)
10
- super
11
- @pagy = pagy
12
- end
6
+ attr_reader :pagy, :variable, :value
13
7
 
14
- def variable
15
- message =~ /expected :(\w+)/
16
- Regexp.last_match(1)&.to_sym
17
- end
18
-
19
- def value
20
- pagy.vars[variable]
8
+ def initialize(pagy, variable, description, value = nil)
9
+ @pagy = pagy
10
+ @variable = variable
11
+ @value = value
12
+ message = +"expected :#{@variable} #{description}"
13
+ message << "; got #{@value.inspect}" if value
14
+ super message
21
15
  end
22
16
  end
23
17
 
24
- # specific overflow error
18
+ # Specific overflow error
25
19
  class OverflowError < VariableError; end
26
20
 
21
+ # I18n configuration error
22
+ class I18nError < StandardError; end
23
+
24
+ # Generic internal error
25
+ class InternalError < StandardError; end
27
26
  end
@@ -2,18 +2,18 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class Pagy
5
- module Backend
5
+ module ArelExtra
6
6
  private
7
7
 
8
- def pagy_arel(collection, vars={})
8
+ def pagy_arel(collection, vars = {})
9
9
  pagy = Pagy.new(pagy_arel_get_vars(collection, vars))
10
- [ pagy, pagy_get_items(collection, pagy) ]
10
+ [pagy, pagy_get_items(collection, pagy)]
11
11
  end
12
12
 
13
13
  def pagy_arel_get_vars(collection, vars)
14
- pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
14
+ pagy_set_items_from_params(vars) if defined?(ItemsExtra)
15
15
  vars[:count] ||= pagy_arel_count(collection)
16
- vars[:page] ||= params[ vars[:page_param] || VARS[:page_param] ]
16
+ vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
17
17
  vars
18
18
  end
19
19
 
@@ -27,6 +27,6 @@ class Pagy
27
27
  collection.unscope(:order).limit(1).pluck(sql).first.to_i
28
28
  end
29
29
  end
30
-
31
30
  end
31
+ Backend.prepend ArelExtra
32
32
  end
@@ -3,22 +3,22 @@
3
3
 
4
4
  class Pagy
5
5
  # Add specialized backend methods to paginate array collections
6
- module Backend
6
+ module ArrayExtra
7
7
  private
8
8
 
9
9
  # Return Pagy object and items
10
- def pagy_array(array, vars={})
10
+ def pagy_array(array, vars = {})
11
11
  pagy = Pagy.new(pagy_array_get_vars(array, vars))
12
- [ pagy, array[pagy.offset, pagy.items] ]
12
+ [pagy, array[pagy.offset, pagy.items]]
13
13
  end
14
14
 
15
15
  # Sub-method called only by #pagy_array: here for easy customization of variables by overriding
16
16
  def pagy_array_get_vars(array, vars)
17
- pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
17
+ pagy_set_items_from_params(vars) if defined?(ItemsExtra)
18
18
  vars[:count] ||= array.size
19
- vars[:page] ||= params[ vars[:page_param] || VARS[:page_param] ]
19
+ vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
20
20
  vars
21
21
  end
22
-
23
22
  end
23
+ Backend.prepend ArrayExtra
24
24
  end
@@ -4,8 +4,7 @@
4
4
  require 'pagy/extras/shared'
5
5
 
6
6
  class Pagy
7
- module Frontend
8
-
7
+ module BootstrapExtra
9
8
  # Pagination for bootstrap: it returns the html with the series of links to the pages
10
9
  def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '')
11
10
  p_id = %( id="#{pagy_id}") if pagy_id
@@ -15,9 +14,13 @@ class Pagy
15
14
  html << pagy_bootstrap_prev_html(pagy, link)
16
15
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
17
16
  html << case item
18
- when Integer then %(<li class="page-item">#{link.call item}</li>)
19
- when String then %(<li class="page-item active">#{link.call item}</li>)
20
- when :gap then %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
17
+ when Integer
18
+ %(<li class="page-item">#{link.call item}</li>)
19
+ when String
20
+ %(<li class="page-item active">#{link.call item}</li>)
21
+ when :gap
22
+ %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
23
+ else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
21
24
  end
22
25
  end
23
26
  html << pagy_bootstrap_next_html(pagy, link)
@@ -25,8 +28,7 @@ class Pagy
25
28
  end
26
29
 
27
30
  # Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.nav javascript
28
- def pagy_bootstrap_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
29
- pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
31
+ def pagy_bootstrap_nav_js(pagy, pagy_id: nil, link_extra: '', steps: nil)
30
32
  p_id = %( id="#{pagy_id}") if pagy_id
31
33
  link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
32
34
  tags = { 'before' => %(<ul class="pagination">#{pagy_bootstrap_prev_html pagy, link}),
@@ -35,52 +37,54 @@ class Pagy
35
37
  'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>),
36
38
  'after' => %(#{pagy_bootstrap_next_html pagy, link}</ul>) }
37
39
 
38
- %(<nav#{p_id} class="pagy-njs pagy-bootstrap-nav-js" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
40
+ %(<nav#{p_id} class="pagy-njs pagy-bootstrap-nav-js" aria-label="pager" #{
41
+ pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
39
42
  end
40
43
 
41
44
  # Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
42
- def pagy_bootstrap_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
43
- pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
45
+ def pagy_bootstrap_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
44
46
  p_id = %( id="#{pagy_id}") if pagy_id
45
47
  link = pagy_link_proc(pagy, link_extra: link_extra)
46
48
  p_page = pagy.page
47
49
  p_pages = pagy.pages
48
- input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" class="text-primary" style="padding: 0; border: none; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
50
+ input = %(<input type="number" min="1" max="#{p_pages}" value="#{
51
+ p_page}" class="text-primary" style="padding: 0; border: none; text-align: center; width: #{
52
+ p_pages.to_s.length + 1}rem;">)
49
53
 
50
54
  %(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination" aria-label="pager"><div class="btn-group" role="group" #{
51
- pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
52
- }>#{
55
+ pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)}>#{
53
56
  if (p_prev = pagy.prev)
54
57
  link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous" class="prev btn btn-primary"'
55
58
  else
56
59
  %(<a class="prev btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.prev')}</a>)
57
60
  end
58
- }<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
61
+ }<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{
62
+ pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
59
63
  if (p_next = pagy.next)
60
64
  link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"'
61
65
  else
62
- %(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next' }</a>)
66
+ %(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next'}</a>)
63
67
  end
64
- }</div></nav>)
68
+ }</div></nav>)
65
69
  end
66
70
 
67
71
  private
68
72
 
69
- def pagy_bootstrap_prev_html(pagy, link)
70
- if (p_prev = pagy.prev)
71
- %(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
72
- else
73
- %(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.prev'}</a></li>)
74
- end
73
+ def pagy_bootstrap_prev_html(pagy, link)
74
+ if (p_prev = pagy.prev)
75
+ %(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
76
+ else
77
+ %(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.prev'}</a></li>)
75
78
  end
79
+ end
76
80
 
77
- def pagy_bootstrap_next_html(pagy, link)
78
- if (p_next = pagy.next)
79
- %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
80
- else
81
- %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.next'}</a></li>)
82
- end
81
+ def pagy_bootstrap_next_html(pagy, link)
82
+ if (p_next = pagy.next)
83
+ %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
84
+ else
85
+ %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.next'}</a></li>)
83
86
  end
84
-
87
+ end
85
88
  end
89
+ Frontend.prepend BootstrapExtra
86
90
  end