pagy 4.10.2 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/config/pagy.rb +71 -44
  3. data/lib/javascripts/pagy.js +15 -6
  4. data/lib/pagy/backend.rb +9 -12
  5. data/lib/pagy/console.rb +6 -4
  6. data/lib/pagy/countless.rb +21 -21
  7. data/lib/pagy/exceptions.rb +16 -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 +35 -29
  11. data/lib/pagy/extras/bulma.rb +43 -32
  12. data/lib/pagy/extras/countless.rb +14 -14
  13. data/lib/pagy/extras/elasticsearch_rails.rb +64 -47
  14. data/lib/pagy/extras/foundation.rb +29 -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 +38 -39
  19. data/lib/pagy/extras/materialize.rb +31 -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 +26 -26
  23. data/lib/pagy/extras/overflow.rb +56 -60
  24. data/lib/pagy/extras/searchkick.rb +51 -45
  25. data/lib/pagy/extras/semantic.rb +31 -30
  26. data/lib/pagy/extras/shared.rb +43 -40
  27. data/lib/pagy/extras/standalone.rb +41 -45
  28. data/lib/pagy/extras/support.rb +20 -13
  29. data/lib/pagy/extras/trim.rb +11 -11
  30. data/lib/pagy/extras/uikit.rb +30 -28
  31. data/lib/pagy/frontend.rb +25 -49
  32. data/lib/pagy/i18n.rb +159 -0
  33. data/lib/pagy/url_helpers.rb +24 -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 +7 -10
  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
@@ -4,8 +4,9 @@
4
4
  require 'pagy/extras/shared'
5
5
 
6
6
  class Pagy
7
- module Frontend
8
-
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module MaterializeExtra
9
10
  # Pagination for materialize: it returns the html with the series of links to the pages
10
11
  def pagy_materialize_nav(pagy, pagy_id: nil, link_extra: '')
11
12
  p_id = %( id="#{pagy_id}") if pagy_id
@@ -18,6 +19,7 @@ class Pagy
18
19
  when Integer then %(<li class="waves-effect">#{link.call item}</li>) # page link
19
20
  when String then %(<li class="active">#{link.call item}</li>) # active page
20
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}"
21
23
  end
22
24
  end
23
25
  html << pagy_materialize_next_html(pagy, link)
@@ -25,8 +27,7 @@ class Pagy
25
27
  end
26
28
 
27
29
  # Javascript pagination for materialize: it returns a nav and a JSON tag used by the Pagy.nav javascript
28
- def pagy_materialize_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
30
+ def pagy_materialize_nav_js(pagy, pagy_id: nil, link_extra: '', steps: nil)
30
31
  p_id = %( id="#{pagy_id}") if pagy_id
31
32
  link = pagy_link_proc(pagy, link_extra: link_extra)
32
33
 
@@ -36,47 +37,47 @@ class Pagy
36
37
  'gap' => %(<li class="gap disabled"><a href="#">#{pagy_t 'pagy.nav.gap'}</a></li>),
37
38
  'after' => %(#{pagy_materialize_next_html pagy, link}</ul>) }
38
39
 
39
- %(<div#{p_id} class="pagy-njs pagy-materialize-nav-js" role="navigation" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></div>)
40
+ %(<div#{p_id} class="pagy-njs pagy-materialize-nav-js" role="navigation" aria-label="pager" #{
41
+ pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></div>)
40
42
  end
41
43
 
42
44
  # Javascript combo pagination for materialize: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
43
- def pagy_materialize_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
44
- pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
45
+ def pagy_materialize_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
45
46
  p_id = %( id="#{pagy_id}") if pagy_id
46
47
  link = pagy_link_proc(pagy, link_extra: link_extra)
47
48
  p_page = pagy.page
48
49
  p_pages = pagy.pages
49
50
  style = ' style="vertical-align: middle"'
50
- input = %(<input type="number" class="browser-default" min="1" max="#{p_pages}" value="#{p_page}" style="text-align: center; width: #{p_pages.to_s.length+1}rem;">)
51
+ input = %(<input type="number" class="browser-default" min="1" max="#{p_pages}" value="#{
52
+ p_page}" style="text-align: center; width: #{p_pages.to_s.length + 1}rem;">)
51
53
 
52
- %(<ul#{p_id} class="pagy-materialize-combo-nav-js pagination chip" role="navigation" aria-label="pager" style="padding-right: 0" #{
53
- pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
54
- }>#{
55
- pagy_materialize_prev_html pagy, link, style
56
- }<li class="pagy-combo-input">#{
57
- pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
58
- }</li>#{
59
- pagy_materialize_next_html pagy, link, style
60
- }</ul>)
54
+ html = %(<ul#{p_id} class="pagy-materialize-combo-nav-js pagination chip" role="navigation")
55
+ %(#{html} aria-label="pager" style="padding-right: 0" #{
56
+ pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)}>#{
57
+ pagy_materialize_prev_html pagy, link, style}<li class="pagy-combo-input">#{
58
+ pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</li>#{
59
+ pagy_materialize_next_html pagy, link, style}</ul>)
61
60
  end
62
61
 
63
62
  private
64
63
 
65
- def pagy_materialize_prev_html(pagy, link, style='')
66
- if (p_prev = pagy.prev)
67
- %(<li class="waves-effect prev"#{style}>#{link.call p_prev, '<i class="material-icons">chevron_left</i>', 'aria-label="previous"'}</li>)
68
- else
69
- %(<li class="prev disabled"#{style}><a href="#"><i class="material-icons">chevron_left</i></a></li>)
70
- end
64
+ def pagy_materialize_prev_html(pagy, link, style = '')
65
+ if (p_prev = pagy.prev)
66
+ %(<li class="waves-effect prev"#{style}>#{
67
+ link.call p_prev, '<i class="material-icons">chevron_left</i>', 'aria-label="previous"'}</li>)
68
+ else
69
+ %(<li class="prev disabled"#{style}><a href="#"><i class="material-icons">chevron_left</i></a></li>)
71
70
  end
71
+ end
72
72
 
73
- def pagy_materialize_next_html(pagy, link, style='')
74
- if (p_next = pagy.next)
75
- %(<li class="waves-effect next"#{style}>#{link.call p_next, '<i class="material-icons">chevron_right</i>', 'aria-label="next"'}</li>)
76
- else
77
- %(<li class="next disabled"#{style}><a href="#"><i class="material-icons">chevron_right</i></a></li>)
78
- end
73
+ def pagy_materialize_next_html(pagy, link, style = '')
74
+ if (p_next = pagy.next)
75
+ %(<li class="waves-effect next"#{style}>#{
76
+ link.call p_next, '<i class="material-icons">chevron_right</i>', 'aria-label="next"'}</li>)
77
+ else
78
+ %(<li class="next disabled"#{style}><a href="#"><i class="material-icons">chevron_right</i></a></li>)
79
79
  end
80
-
80
+ end
81
81
  end
82
+ Frontend.prepend MaterializeExtra
82
83
  end
@@ -1,55 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Pagy
4
-
5
- VARS[:meilisearch_search_method] ||= :pagy_search
6
-
7
- module Meilisearch
8
- # returns an array used to delay the call of #search
9
- # after the pagination variables are merged to the options
10
- def pagy_meilisearch(term = nil, **vars)
11
- [self, term, vars]
4
+ DEFAULT[:meilisearch_search_method] ||= :pagy_search
5
+
6
+ module MeilisearchExtra
7
+ module Meilisearch
8
+ # Return an array used to delay the call of #search
9
+ # after the pagination variables are merged to the options
10
+ def pagy_meilisearch(term = nil, **vars)
11
+ [self, term, vars]
12
+ end
13
+ alias_method DEFAULT[:meilisearch_search_method], :pagy_meilisearch
12
14
  end
13
- alias_method VARS[:meilisearch_search_method], :pagy_meilisearch
14
- end
15
-
16
- # create a Pagy object from a Meilisearch results
17
- def self.new_from_meilisearch(results, vars={})
18
- vars[:items] = results.raw_answer['limit']
19
- vars[:page] = [results.raw_answer['offset'] / vars[:items], 1].max
20
- vars[:count] = results.raw_answer['nbHits']
21
- new(vars)
22
- end
23
15
 
24
- # Add specialized backend methods to paginate Meilisearch results
25
- module Backend
26
- private
27
-
28
- # Return Pagy object and results
29
- def pagy_meilisearch(pagy_search_args, vars = {})
30
- model, term, options = pagy_search_args
31
- vars = pagy_meilisearch_get_vars(nil, vars)
32
- options[:limit] = vars[:items]
33
- options[:offset] = (vars[:page] - 1) * vars[:items]
34
- results = model.search(term, **options)
35
- vars[:count] = results.raw_answer['nbHits']
36
-
37
- pagy = Pagy.new(vars)
38
- # with :last_page overflow we need to re-run the method in order to get the hits
39
- return pagy_meilisearch(pagy_search_args, vars.merge(page: pagy.page)) \
40
- if defined?(Pagy::UseOverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
41
-
42
- [ pagy, results ]
16
+ # Additions for the Pagy class
17
+ module Pagy
18
+ # Create a Pagy object from a Meilisearch results
19
+ def new_from_meilisearch(results, vars = {})
20
+ vars[:items] = results.raw_answer['limit']
21
+ vars[:page] = [results.raw_answer['offset'] / vars[:items], 1].max
22
+ vars[:count] = results.raw_answer['nbHits']
23
+ new(vars)
24
+ end
43
25
  end
44
26
 
45
- # Sub-method called only by #pagy_meilisearch: here for easy customization of variables by overriding
46
- # the _collection argument is not available when the method is called
47
- def pagy_meilisearch_get_vars(_collection, vars)
48
- pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
49
- vars[:items] ||= VARS[:items]
50
- vars[:page] ||= (params[ vars[:page_param] || VARS[:page_param] ] || 1).to_i
51
- vars
27
+ # Add specialized backend methods to paginate Meilisearch results
28
+ module Backend
29
+ private
30
+
31
+ # Return Pagy object and results
32
+ def pagy_meilisearch(pagy_search_args, vars = {})
33
+ model, term, options = pagy_search_args
34
+ vars = pagy_meilisearch_get_vars(nil, vars)
35
+ options[:limit] = vars[:items]
36
+ options[:offset] = (vars[:page] - 1) * vars[:items]
37
+ results = model.search(term, **options)
38
+ vars[:count] = results.raw_answer['nbHits']
39
+ pagy = ::Pagy.new(vars)
40
+ # with :last_page overflow we need to re-run the method in order to get the hits
41
+ return pagy_meilisearch(pagy_search_args, vars.merge(page: pagy.page)) \
42
+ if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
43
+
44
+ [pagy, results]
45
+ end
46
+
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
+ def pagy_meilisearch_get_vars(_collection, vars)
50
+ pagy_set_items_from_params(vars) if defined?(ItemsExtra)
51
+ vars[:items] ||= DEFAULT[:items]
52
+ vars[:page] ||= (params[vars[:page_param] || DEFAULT[:page_param]] || 1).to_i
53
+ vars
54
+ end
52
55
  end
53
-
54
56
  end
57
+ Meilisearch = MeilisearchExtra::Meilisearch
58
+ extend MeilisearchExtra::Pagy
59
+ Backend.prepend MeilisearchExtra::Backend
55
60
  end
@@ -1,31 +1,23 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/metadata
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
5
- # Add a specialized backend method for pagination metadata
6
- module Backend
7
- private
8
-
9
- METADATA = %i[ scaffold_url first_url prev_url page_url next_url last_url
10
- count page items vars pages last from to prev next series
11
- ].tap do |metadata|
12
- metadata << :sequels if VARS.key?(:steps) # :steps gets defined along with the #sequels method
13
- end.freeze
4
+ require 'pagy/url_helpers'
14
5
 
15
- VARS[:metadata] = METADATA.dup
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 ]
16
9
 
17
- include Helpers
10
+ # Add a specialized backend method for pagination metadata
11
+ module MetadataExtra
12
+ private
18
13
 
19
- def pagy_metadata(pagy, deprecated_url=nil, absolute: nil)
20
- absolute = Pagy.deprecated_arg(:url, deprecated_url, :absolute, absolute) if deprecated_url
21
- names = pagy.vars[:metadata]
22
- unknown = names - METADATA
23
- raise VariableError.new(pagy), "unknown metadata #{unknown.inspect}" \
24
- unless unknown.empty?
14
+ include UrlHelpers
25
15
 
16
+ # Return the metadata hash
17
+ def pagy_metadata(pagy, absolute: nil)
26
18
  scaffold_url = pagy_url_for(pagy, PAGE_PLACEHOLDER, absolute: absolute)
27
19
  {}.tap do |metadata|
28
- names.each do |key|
20
+ pagy.vars[:metadata].each do |key|
29
21
  metadata[key] = case key
30
22
  when :scaffold_url then scaffold_url
31
23
  when :first_url then scaffold_url.sub(PAGE_PLACEHOLDER, 1.to_s)
@@ -35,9 +27,11 @@ class Pagy
35
27
  when :last_url then scaffold_url.sub(PAGE_PLACEHOLDER, pagy.last.to_s)
36
28
  else pagy.send(key)
37
29
  end
30
+ rescue NoMethodError
31
+ raise VariableError.new(pagy, :metadata, 'to contain known keys', key)
38
32
  end
39
33
  end
40
34
  end
41
-
42
35
  end
36
+ Backend.prepend MetadataExtra
43
37
  end
@@ -4,11 +4,11 @@
4
4
  require 'pagy/extras/shared'
5
5
 
6
6
  class Pagy
7
- module Frontend
8
-
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module NavsExtra
9
10
  # Javascript pagination: it returns a nav and a JSON tag used by the Pagy.nav javascript
10
- def pagy_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
11
- pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
11
+ def pagy_nav_js(pagy, pagy_id: nil, link_extra: '', steps: nil)
12
12
  p_id = %( id="#{pagy_id}") if pagy_id
13
13
  link = pagy_link_proc(pagy, link_extra: link_extra)
14
14
  tags = { 'before' => pagy_nav_prev_html(pagy, link),
@@ -17,46 +17,46 @@ class Pagy
17
17
  'gap' => %(<span class="page gap">#{pagy_t 'pagy.nav.gap'}</span> ),
18
18
  'after' => pagy_nav_next_html(pagy, link) }
19
19
 
20
- %(<nav#{p_id} class="pagy-njs pagy-nav-js pagination" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
20
+ %(<nav#{p_id} class="pagy-njs pagy-nav-js pagination" aria-label="pager" #{
21
+ pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
21
22
  end
22
23
 
23
24
  # Javascript combo pagination: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
24
- def pagy_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
25
- pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
25
+ def pagy_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
26
26
  p_id = %( id="#{pagy_id}") if pagy_id
27
27
  link = pagy_link_proc(pagy, link_extra: link_extra)
28
28
  p_page = pagy.page
29
29
  p_pages = pagy.pages
30
- input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
30
+ input = %(<input type="number" min="1" max="#{p_pages}" value="#{
31
+ p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length + 1}rem;">)
31
32
 
32
33
  %(<nav#{p_id} class="pagy-combo-nav-js pagination" aria-label="pager" #{
33
- pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
34
- }>#{
34
+ pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)}>#{
35
35
  pagy_nav_prev_html pagy, link
36
- }<span class="pagy-combo-input" style="margin: 0 0.6rem;">#{
36
+ }<span class="pagy-combo-input" style="margin: 0 0.6rem;">#{
37
37
  pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
38
- }</span> #{
38
+ }</span> #{
39
39
  pagy_nav_next_html pagy, link
40
- }</nav>)
40
+ }</nav>)
41
41
  end
42
42
 
43
43
  private
44
44
 
45
- def pagy_nav_prev_html(pagy, link)
46
- if (p_prev = pagy.prev)
47
- %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
48
- else
49
- %(<span class="page prev disabled">#{pagy_t 'pagy.nav.prev'}</span> )
50
- end
45
+ def pagy_nav_prev_html(pagy, link)
46
+ if (p_prev = pagy.prev)
47
+ %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
48
+ else
49
+ %(<span class="page prev disabled">#{pagy_t 'pagy.nav.prev'}</span> )
51
50
  end
51
+ end
52
52
 
53
- def pagy_nav_next_html(pagy, link)
54
- if (p_next = pagy.next)
55
- %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
56
- else
57
- %(<span class="page next disabled">#{pagy_t 'pagy.nav.next'}</span>)
58
- end
53
+ def pagy_nav_next_html(pagy, link)
54
+ if (p_next = pagy.next)
55
+ %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
56
+ else
57
+ %(<span class="page next disabled">#{pagy_t 'pagy.nav.next'}</span>)
59
58
  end
60
-
59
+ end
61
60
  end
61
+ Frontend.prepend NavsExtra
62
62
  end
@@ -2,76 +2,72 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class Pagy
5
+ DEFAULT[:overflow] = :empty_page
5
6
 
6
- module UseOverflowExtra
7
- VARS[:overflow] = :empty_page
8
-
9
- def overflow?
10
- @overflow
11
- end
12
-
13
- def initialize(vars)
14
- @overflow ||= false # don't override if :last_page re-run the method after an overflow
15
- super
16
- rescue OverflowError
17
- @overflow = true # add the overflow flag
18
- case @vars[:overflow]
19
- when :exception
20
- raise # same as without the extra
21
- when :last_page
22
- initial_page = @vars[:page] # save the very initial page (even after re-run)
23
- initialize vars.merge!(page: @last) # re-run with the last page
24
- @vars[:page] = initial_page # restore the inital page
25
- when :empty_page
26
- @offset = @items = @from = @to = 0 # vars relative to the actual page
27
- @prev = @last # prev relative to the actual page
28
- extend Series # special series for :empty_page
29
- else
30
- raise VariableError.new(self), "expected :overflow variable in [:last_page, :empty_page, :exception]; got #{@vars[:overflow].inspect}"
7
+ # Handles OverflowError exceptions with different options
8
+ module OverflowExtra
9
+ # Support for Pagy class
10
+ module Pagy
11
+ # Is the requested page overflowing?
12
+ def overflow?
13
+ @overflow
31
14
  end
32
- end
33
15
 
34
- module Series
35
- def series(size=@vars[:size])
36
- @page = @last # series for last page
37
- super(size).tap do |s| # call original series
38
- s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
39
- @page = @vars[:page] # restore the actual page
16
+ # Add rescue clause for different behaviors
17
+ def initialize(vars)
18
+ @overflow ||= false # don't override if :last_page re-run the method after an overflow
19
+ super
20
+ rescue OverflowError
21
+ @overflow = true # add the overflow flag
22
+ case @vars[:overflow]
23
+ when :exception
24
+ raise # same as without the extra
25
+ when :last_page
26
+ initial_page = @vars[:page] # save the very initial page (even after re-run)
27
+ initialize vars.merge!(page: @last) # re-run with the last page
28
+ @vars[:page] = initial_page # restore the initial page
29
+ when :empty_page
30
+ @offset = @items = @from = @to = 0 # vars relative to the actual page
31
+ @prev = @last # prev relative to the actual page
32
+ extend Series # special series for :empty_page
33
+ else
34
+ raise VariableError.new(self, :overflow, 'to be in [:last_page, :empty_page, :exception]', @vars[:overflow])
40
35
  end
41
36
  end
42
- end
43
-
44
- end
45
- prepend UseOverflowExtra
46
-
47
37
 
48
- # support for Pagy::Countless
49
- if defined?(Pagy::Countless)
50
- class Countless
51
-
52
- module UseOverflowExtra
53
-
54
- def finalize(items)
55
- @overflow = false
56
- super
57
- rescue OverflowError
58
- @overflow = true # add the overflow flag
59
- case @vars[:overflow]
60
- when :exception
61
- raise # same as without the extra
62
- when :empty_page
63
- @offset = @items = @from = @to = 0 # vars relative to the actual page
64
- @vars[:size] = [] # no page in the series
65
- self
66
- else
67
- raise VariableError.new(self), "expected :overflow variable in [:empty_page, :exception]; got #{@vars[:overflow].inspect}"
38
+ # Special series for empty page
39
+ module Series
40
+ def series(size = @vars[:size])
41
+ @page = @last # series for last page
42
+ super(size).tap do |s| # call original series
43
+ s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
44
+ @page = @vars[:page] # restore the actual page
68
45
  end
69
46
  end
70
-
71
47
  end
72
- prepend UseOverflowExtra
48
+ end
73
49
 
50
+ # Support for Pagy::Countless class
51
+ module Countless
52
+ # Add rescue clause for different behaviors
53
+ def finalize(items)
54
+ @overflow = false
55
+ super
56
+ rescue OverflowError
57
+ @overflow = true # add the overflow flag
58
+ case @vars[:overflow]
59
+ when :exception
60
+ raise # same as without the extra
61
+ when :empty_page
62
+ @offset = @items = @from = @to = 0 # vars relative to the actual page
63
+ @vars[:size] = [] # no page in the series
64
+ self
65
+ else
66
+ raise VariableError.new(self, :overflow, 'to be in [:empty_page, :exception]', @vars[:overflow])
67
+ end
68
+ end
74
69
  end
75
70
  end
76
-
71
+ prepend OverflowExtra::Pagy
72
+ Countless.prepend OverflowExtra::Countless if defined?(Countless)
77
73
  end
@@ -2,58 +2,64 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class Pagy
5
+ DEFAULT[:searchkick_search_method] ||= :pagy_search
5
6
 
6
- VARS[:searchkick_search_method] ||= :pagy_search
7
+ module SearchkickExtra
8
+ module Searchkick
9
+ # Return an array used to delay the call of #search
10
+ # after the pagination variables are merged to the options.
11
+ # It also pushes to the same array an optional method call.
12
+ def pagy_searchkick(term = '*', **options, &block)
13
+ [self, term, options, block].tap do |args|
14
+ args.define_singleton_method(:method_missing) { |*a| args += a }
15
+ end
16
+ end
17
+ alias_method Pagy::DEFAULT[:searchkick_search_method], :pagy_searchkick
18
+ end
7
19
 
8
- module Searchkick
9
- # returns an array used to delay the call of #search
10
- # after the pagination variables are merged to the options
11
- # it also pushes to the same array an eventually called method
12
- def pagy_searchkick(term = '*', **options, &block)
13
- [self, term, options, block].tap do |args|
14
- args.define_singleton_method(:method_missing){|*a| args += a}
20
+ # Additions for the Pagy class
21
+ module Pagy
22
+ # Create a Pagy object from a Searchkick::Results object
23
+ def new_from_searchkick(results, vars = {})
24
+ vars[:items] = results.options[:per_page]
25
+ vars[:page] = results.options[:page]
26
+ vars[:count] = results.total_count
27
+ new(vars)
15
28
  end
16
29
  end
17
- alias_method VARS[:searchkick_search_method], :pagy_searchkick
18
- end
19
30
 
20
- # create a Pagy object from a Searchkick::Results object
21
- def self.new_from_searchkick(results, vars={})
22
- vars[:items] = results.options[:per_page]
23
- vars[:page] = results.options[:page]
24
- vars[:count] = results.total_count
25
- new(vars)
26
- end
31
+ # Add specialized backend methods to paginate Searchkick::Results
32
+ module Backend
33
+ private
27
34
 
28
- # Add specialized backend methods to paginate Searchkick::Results
29
- module Backend
30
- private
31
-
32
- # Return Pagy object and results
33
- def pagy_searchkick(pagy_search_args, vars={})
34
- model, term, options, block, *called = pagy_search_args
35
- vars = pagy_searchkick_get_vars(nil, vars)
36
- options[:per_page] = vars[:items]
37
- options[:page] = vars[:page]
38
- results = model.search(term, **options, &block)
39
- vars[:count] = results.total_count
40
-
41
- pagy = Pagy.new(vars)
42
- # with :last_page overflow we need to re-run the method in order to get the hits
43
- return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page)) \
44
- if defined?(Pagy::UseOverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
45
-
46
- [ pagy, called.empty? ? results : results.send(*called) ]
47
- end
35
+ # Return Pagy object and results
36
+ def pagy_searchkick(pagy_search_args, vars = {})
37
+ model, term, options, block, *called = pagy_search_args
38
+ vars = pagy_searchkick_get_vars(nil, vars)
39
+ options[:per_page] = vars[:items]
40
+ options[:page] = vars[:page]
41
+ results = model.search(term, **options, &block)
42
+ vars[:count] = results.total_count
48
43
 
49
- # Sub-method called only by #pagy_searchkick: here for easy customization of variables by overriding
50
- # the _collection argument is not available when the method is called
51
- def pagy_searchkick_get_vars(_collection, vars)
52
- pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
53
- vars[:items] ||= VARS[:items]
54
- vars[:page] ||= (params[ vars[:page_param] || VARS[:page_param] ] || 1).to_i
55
- vars
56
- end
44
+ pagy = ::Pagy.new(vars)
45
+ # with :last_page overflow we need to re-run the method in order to get the hits
46
+ return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page)) \
47
+ if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
48
+
49
+ [pagy, called.empty? ? results : results.send(*called)]
50
+ end
57
51
 
52
+ # Sub-method called only by #pagy_searchkick: here for easy customization of variables by overriding
53
+ # the _collection argument is not available when the method is called
54
+ def pagy_searchkick_get_vars(_collection, vars)
55
+ pagy_set_items_from_params(vars) if defined?(ItemsExtra)
56
+ vars[:items] ||= DEFAULT[:items]
57
+ vars[:page] ||= (params[vars[:page_param] || DEFAULT[:page_param]] || 1).to_i
58
+ vars
59
+ end
60
+ end
58
61
  end
62
+ Searchkick = SearchkickExtra::Searchkick
63
+ extend SearchkickExtra::Pagy
64
+ Backend.prepend SearchkickExtra::Backend
59
65
  end