pagy 4.11.0 → 6.0.0

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/lib/config/pagy.rb +119 -58
  4. data/lib/javascripts/pagy-dev.js +114 -0
  5. data/lib/javascripts/pagy-module.d.ts +5 -0
  6. data/lib/javascripts/pagy-module.js +113 -0
  7. data/lib/javascripts/pagy.js +1 -121
  8. data/lib/locales/de.yml +1 -1
  9. data/lib/locales/ko.yml +1 -1
  10. data/lib/locales/nn.yml +22 -0
  11. data/lib/locales/ta.yml +22 -0
  12. data/lib/pagy/backend.rb +10 -13
  13. data/lib/pagy/calendar/day.rb +39 -0
  14. data/lib/pagy/calendar/helper.rb +61 -0
  15. data/lib/pagy/calendar/month.rb +40 -0
  16. data/lib/pagy/calendar/quarter.rb +47 -0
  17. data/lib/pagy/calendar/week.rb +39 -0
  18. data/lib/pagy/calendar/year.rb +33 -0
  19. data/lib/pagy/calendar.rb +100 -0
  20. data/lib/pagy/console.rb +6 -4
  21. data/lib/pagy/countless.rb +22 -23
  22. data/lib/pagy/exceptions.rb +14 -16
  23. data/lib/pagy/extras/arel.rb +11 -7
  24. data/lib/pagy/extras/array.rb +9 -9
  25. data/lib/pagy/extras/bootstrap.rb +45 -38
  26. data/lib/pagy/extras/bulma.rb +50 -38
  27. data/lib/pagy/extras/calendar.rb +49 -0
  28. data/lib/pagy/extras/countless.rb +15 -18
  29. data/lib/pagy/extras/elasticsearch_rails.rb +67 -48
  30. data/lib/pagy/extras/foundation.rb +39 -35
  31. data/lib/pagy/extras/frontend_helpers.rb +72 -0
  32. data/lib/pagy/extras/gearbox.rb +54 -0
  33. data/lib/pagy/extras/headers.rb +30 -20
  34. data/lib/pagy/extras/i18n.rb +15 -13
  35. data/lib/pagy/extras/items.rb +42 -40
  36. data/lib/pagy/extras/materialize.rb +40 -38
  37. data/lib/pagy/extras/meilisearch.rb +53 -44
  38. data/lib/pagy/extras/metadata.rb +15 -20
  39. data/lib/pagy/extras/navs.rb +35 -34
  40. data/lib/pagy/extras/overflow.rb +62 -61
  41. data/lib/pagy/extras/searchkick.rb +54 -46
  42. data/lib/pagy/extras/semantic.rb +42 -40
  43. data/lib/pagy/extras/standalone.rb +50 -46
  44. data/lib/pagy/extras/support.rb +24 -16
  45. data/lib/pagy/extras/trim.rb +15 -14
  46. data/lib/pagy/extras/uikit.rb +41 -38
  47. data/lib/pagy/frontend.rb +36 -59
  48. data/lib/pagy/i18n.rb +164 -0
  49. data/lib/pagy/url_helpers.rb +24 -0
  50. data/lib/pagy.rb +90 -31
  51. data/lib/templates/bootstrap_nav.html.erb +2 -2
  52. data/lib/templates/bootstrap_nav.html.haml +2 -2
  53. data/lib/templates/bootstrap_nav.html.slim +2 -2
  54. data/lib/templates/foundation_nav.html.erb +1 -1
  55. data/lib/templates/foundation_nav.html.haml +1 -1
  56. data/lib/templates/foundation_nav.html.slim +1 -1
  57. data/lib/templates/nav.html.erb +1 -1
  58. data/lib/templates/nav.html.haml +1 -1
  59. data/lib/templates/nav.html.slim +1 -1
  60. data/lib/templates/uikit_nav.html.erb +2 -2
  61. data/lib/templates/uikit_nav.html.haml +1 -1
  62. data/lib/templates/uikit_nav.html.slim +2 -2
  63. metadata +29 -13
  64. data/lib/locales/utils/i18n.rb +0 -17
  65. data/lib/locales/utils/loader.rb +0 -31
  66. data/lib/locales/utils/p11n.rb +0 -112
  67. data/lib/pagy/deprecation.rb +0 -27
  68. data/lib/pagy/extras/shared.rb +0 -52
@@ -1,82 +1,84 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/materialize
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy/extras/shared'
5
-
6
- class Pagy
7
- module Frontend
4
+ require 'pagy/extras/frontend_helpers'
8
5
 
6
+ class Pagy # :nodoc:
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
- def pagy_materialize_nav(pagy, pagy_id: nil, link_extra: '')
11
+ def pagy_materialize_nav(pagy, pagy_id: nil, link_extra: '', **vars)
11
12
  p_id = %( id="#{pagy_id}") if pagy_id
12
13
  link = pagy_link_proc(pagy, link_extra: link_extra)
13
14
 
14
- html = +%(<div#{p_id} class="pagy-materialize-nav pagination" role="navigation" aria-label="pager"><ul class="pagination">)
15
+ html = +%(<div#{p_id} class="pagy-materialize-nav pagination" role="navigation"><ul class="pagination">)
15
16
  html << pagy_materialize_prev_html(pagy, link)
16
- pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
17
+ pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
17
18
  html << case item
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)
24
26
  html << %(</ul></div>)
25
27
  end
26
28
 
27
- # 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
29
+ # Javascript pagination for materialize: it returns a nav and a JSON tag used by the pagy.js file
30
+ def pagy_materialize_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
31
+ sequels = pagy.sequels(**vars)
30
32
  p_id = %( id="#{pagy_id}") if pagy_id
31
33
  link = pagy_link_proc(pagy, link_extra: link_extra)
32
34
 
33
35
  tags = { 'before' => %(<ul class="pagination">#{pagy_materialize_prev_html pagy, link}),
34
- 'link' => %(<li class="waves-effect">#{mark = link.call(PAGE_PLACEHOLDER)}</li>),
36
+ 'link' => %(<li class="waves-effect">#{mark = link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER)}</li>),
35
37
  'active' => %(<li class="active">#{mark}</li>),
36
38
  'gap' => %(<li class="gap disabled"><a href="#">#{pagy_t 'pagy.nav.gap'}</a></li>),
37
39
  'after' => %(#{pagy_materialize_next_html pagy, link}</ul>) }
38
40
 
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>)
41
+ %(<div#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-materialize-nav-js" role="navigation" #{
42
+ pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></div>)
40
43
  end
41
44
 
42
- # 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
+ # Javascript combo pagination for materialize: it returns a nav and a JSON tag used by the pagy.js file
46
+ def pagy_materialize_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
45
47
  p_id = %( id="#{pagy_id}") if pagy_id
46
48
  link = pagy_link_proc(pagy, link_extra: link_extra)
47
49
  p_page = pagy.page
48
50
  p_pages = pagy.pages
49
51
  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;">)
52
+ input = %(<input type="number" class="browser-default" min="1" max="#{p_pages}" value="#{
53
+ p_page}" style="text-align: center; width: #{p_pages.to_s.length + 1}rem;">)
51
54
 
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>)
55
+ html = %(<ul#{p_id} class="pagy-materialize-combo-nav-js pagination chip" role="navigation")
56
+ %(#{html} style="padding-right: 0" #{
57
+ pagy_data(pagy, :combo, pagy_marked_link(link))}>#{
58
+ pagy_materialize_prev_html pagy, link, style}<li class="pagy-combo-input">#{
59
+ pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</li>#{
60
+ pagy_materialize_next_html pagy, link, style}</ul>)
61
61
  end
62
62
 
63
63
  private
64
64
 
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
65
+ def pagy_materialize_prev_html(pagy, link, style = '')
66
+ if (p_prev = pagy.prev)
67
+ %(<li class="waves-effect prev"#{style}>#{
68
+ link.call p_prev, '<i class="material-icons">chevron_left</i>', 'aria-label="previous"'}</li>)
69
+ else
70
+ %(<li class="prev disabled"#{style}><a href="#"><i class="material-icons">chevron_left</i></a></li>)
71
71
  end
72
+ end
72
73
 
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
74
+ def pagy_materialize_next_html(pagy, link, style = '')
75
+ if (p_next = pagy.next)
76
+ %(<li class="waves-effect next"#{style}>#{
77
+ link.call p_next, '<i class="material-icons">chevron_right</i>', 'aria-label="next"'}</li>)
78
+ else
79
+ %(<li class="next disabled"#{style}><a href="#"><i class="material-icons">chevron_right</i></a></li>)
79
80
  end
80
-
81
+ end
81
82
  end
83
+ Frontend.prepend MaterializeExtra
82
84
  end
@@ -1,55 +1,64 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Pagy
3
+ class Pagy # :nodoc:
4
+ DEFAULT[:meilisearch_search] ||= :ms_search
5
+ DEFAULT[:meilisearch_pagy_search] ||= :pagy_search
4
6
 
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]
7
+ # Paginate Meilisearch results
8
+ module MeilisearchExtra
9
+ module Meilisearch # :nodoc:
10
+ # Return an array used to delay the call of #search
11
+ # after the pagination variables are merged to the options
12
+ def pagy_meilisearch(term = nil, **vars)
13
+ [self, term, vars]
14
+ end
15
+ alias_method DEFAULT[:meilisearch_pagy_search], :pagy_meilisearch
12
16
  end
13
- alias_method VARS[:meilisearch_search_method], :pagy_meilisearch
14
- end
15
17
 
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
18
+ # Additions for the Pagy class
19
+ module Pagy
20
+ # Create a Pagy object from a Meilisearch results
21
+ def new_from_meilisearch(results, vars = {})
22
+ vars[:items] = results.raw_answer['hitsPerPage']
23
+ vars[:page] = results.raw_answer['page']
24
+ vars[:count] = results.raw_answer['totalHits']
23
25
 
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 ]
26
+ new(vars)
27
+ end
43
28
  end
44
29
 
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
52
- end
30
+ # Add specialized backend methods to paginate Meilisearch results
31
+ module Backend
32
+ private
53
33
 
34
+ # Return Pagy object and results
35
+ def pagy_meilisearch(pagy_search_args, vars = {})
36
+ model, term, options = pagy_search_args
37
+ vars = pagy_meilisearch_get_vars(nil, vars)
38
+ options[:hits_per_page] = vars[:items]
39
+ options[:page] = vars[:page]
40
+ results = model.send(:ms_search, term, **options)
41
+ vars[:count] = results.raw_answer['totalHits']
42
+
43
+ pagy = ::Pagy.new(vars)
44
+ # with :last_page overflow we need to re-run the method in order to get the hits
45
+ return pagy_meilisearch(pagy_search_args, vars.merge(page: pagy.page)) \
46
+ if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
47
+
48
+ [pagy, results]
49
+ end
50
+
51
+ # Sub-method called only by #pagy_meilisearch: here for easy customization of variables by overriding.
52
+ # The _collection argument is not available when the method is called.
53
+ def pagy_meilisearch_get_vars(_collection, vars)
54
+ pagy_set_items_from_params(vars) if defined?(ItemsExtra)
55
+ vars[:items] ||= DEFAULT[:items]
56
+ vars[:page] ||= (params[vars[:page_param] || DEFAULT[:page_param]] || 1).to_i
57
+ vars
58
+ end
59
+ end
54
60
  end
61
+ Meilisearch = MeilisearchExtra::Meilisearch
62
+ extend MeilisearchExtra::Pagy
63
+ Backend.prepend MeilisearchExtra::Backend
55
64
  end
@@ -1,31 +1,24 @@
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 # :nodoc:
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
+ keys = defined?(Calendar) && pagy.is_a?(Calendar) ? pagy.vars[:metadata] - %i[count items] : pagy.vars[:metadata]
21
+ keys.each do |key|
29
22
  metadata[key] = case key
30
23
  when :scaffold_url then scaffold_url
31
24
  when :first_url then scaffold_url.sub(PAGE_PLACEHOLDER, 1.to_s)
@@ -35,9 +28,11 @@ class Pagy
35
28
  when :last_url then scaffold_url.sub(PAGE_PLACEHOLDER, pagy.last.to_s)
36
29
  else pagy.send(key)
37
30
  end
31
+ rescue NoMethodError
32
+ raise VariableError.new(pagy, :metadata, 'to contain known keys', key)
38
33
  end
39
34
  end
40
35
  end
41
-
42
36
  end
37
+ Backend.prepend MetadataExtra
43
38
  end
@@ -1,62 +1,63 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/navs
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy/extras/shared'
5
-
6
- class Pagy
7
- module Frontend
8
-
9
- # 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
4
+ require 'pagy/extras/frontend_helpers'
5
+
6
+ class Pagy # :nodoc:
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
10
+ # Javascript pagination: it returns a nav and a JSON tag used by the pagy.js file
11
+ def pagy_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
12
+ sequels = pagy.sequels(**vars)
12
13
  p_id = %( id="#{pagy_id}") if pagy_id
13
14
  link = pagy_link_proc(pagy, link_extra: link_extra)
14
15
  tags = { 'before' => pagy_nav_prev_html(pagy, link),
15
- 'link' => %(<span class="page">#{link.call(PAGE_PLACEHOLDER)}</span> ),
16
- 'active' => %(<span class="page active">#{pagy.page}</span> ),
16
+ 'link' => %(<span class="page">#{link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER)}</span> ),
17
+ 'active' => %(<span class="page active">#{LABEL_PLACEHOLDER}</span> ),
17
18
  'gap' => %(<span class="page gap">#{pagy_t 'pagy.nav.gap'}</span> ),
18
19
  'after' => pagy_nav_next_html(pagy, link) }
19
20
 
20
- %(<nav#{p_id} class="pagy-njs pagy-nav-js pagination" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
21
+ %(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-nav-js pagination" #{
22
+ pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
21
23
  end
22
24
 
23
- # 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
+ # Javascript combo pagination: it returns a nav and a JSON tag used by the pagy.js file
26
+ def pagy_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
26
27
  p_id = %( id="#{pagy_id}") if pagy_id
27
28
  link = pagy_link_proc(pagy, link_extra: link_extra)
28
29
  p_page = pagy.page
29
30
  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;">)
31
+ input = %(<input type="number" min="1" max="#{p_pages}" value="#{
32
+ p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length + 1}rem;">)
31
33
 
32
- %(<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
+ %(<nav#{p_id} class="pagy-combo-nav-js pagination" #{
35
+ pagy_data(pagy, :combo, pagy_marked_link(link))}>#{
35
36
  pagy_nav_prev_html pagy, link
36
- }<span class="pagy-combo-input" style="margin: 0 0.6rem;">#{
37
+ }<span class="pagy-combo-input" style="margin: 0 0.6rem;">#{
37
38
  pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
38
- }</span> #{
39
+ }</span> #{
39
40
  pagy_nav_next_html pagy, link
40
- }</nav>)
41
+ }</nav>)
41
42
  end
42
43
 
43
44
  private
44
45
 
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
46
+ def pagy_nav_prev_html(pagy, link)
47
+ if (p_prev = pagy.prev)
48
+ %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
49
+ else
50
+ %(<span class="page prev disabled">#{pagy_t 'pagy.nav.prev'}</span> )
51
51
  end
52
+ end
52
53
 
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
54
+ def pagy_nav_next_html(pagy, link)
55
+ if (p_next = pagy.next)
56
+ %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
57
+ else
58
+ %(<span class="page next disabled">#{pagy_t 'pagy.nav.next'}</span>)
59
59
  end
60
-
60
+ end
61
61
  end
62
+ Frontend.prepend NavsExtra
62
63
  end
@@ -1,77 +1,78 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/overflow
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
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 for different classes 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 # still true 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
+ requested_page = @vars[:page] # save the requested page (even after re-run)
27
+ initialize vars.merge!(page: @last) # re-run with the last page
28
+ @vars[:page] = requested_page # restore the requested page
29
+ when :empty_page
30
+ @offset = @items = @from = @to = 0 # vars relative to the actual page
31
+ if defined?(Calendar) && is_a?(Calendar) # only for Calendar instances
32
+ edge = @order == :asc ? @final : @initial # get the edge of the overflow side (neat, but any time would do)
33
+ @from = @to = edge # set both to the edge utc time (a >=&&< query will get no records)
34
+ end
35
+ @prev = @last # prev relative to the actual page
36
+ extend Series # special series for :empty_page
37
+ else
38
+ raise VariableError.new(self, :overflow, 'to be in [:last_page, :empty_page, :exception]', @vars[:overflow])
40
39
  end
41
40
  end
42
- end
43
-
44
- end
45
- prepend UseOverflowExtra
46
41
 
47
-
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}"
42
+ # Special series for empty page
43
+ module Series
44
+ def series(*)
45
+ @page = @last # series for last page
46
+ super.tap do |s| # call original series
47
+ s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
48
+ @page = @vars[:page] # restore the actual page
68
49
  end
69
50
  end
70
-
71
51
  end
72
- prepend UseOverflowExtra
52
+ end
73
53
 
54
+ # Support for Pagy::Countless class
55
+ module Countless
56
+ # Add rescue clause for different behaviors
57
+ def finalize(items)
58
+ @overflow = false
59
+ super
60
+ rescue OverflowError
61
+ @overflow = true # add the overflow flag
62
+ case @vars[:overflow]
63
+ when :exception
64
+ raise # same as without the extra
65
+ when :empty_page
66
+ @offset = @items = @from = @to = 0 # vars relative to the actual page
67
+ @vars[:size] = [] # no page in the series
68
+ self
69
+ else
70
+ raise VariableError.new(self, :overflow, 'to be in [:empty_page, :exception]', @vars[:overflow])
71
+ end
72
+ end
74
73
  end
75
74
  end
76
-
75
+ prepend OverflowExtra::Pagy
76
+ Calendar.prepend OverflowExtra::Pagy if defined?(Calendar)
77
+ Countless.prepend OverflowExtra::Countless if defined?(Countless)
77
78
  end
@@ -1,59 +1,67 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/searchkick
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
+ DEFAULT[:searchkick_search] ||= :search
6
+ DEFAULT[:searchkick_pagy_search] ||= :pagy_search
5
7
 
6
- VARS[:searchkick_search_method] ||= :pagy_search
8
+ # Paginate Searchkick::Results objects
9
+ module SearchkickExtra
10
+ module Searchkick # :nodoc:
11
+ # Return an array used to delay the call of #search
12
+ # after the pagination variables are merged to the options.
13
+ # It also pushes to the same array an optional method call.
14
+ def pagy_searchkick(term = '*', **options, &block)
15
+ [self, term, options, block].tap do |args|
16
+ args.define_singleton_method(:method_missing) { |*a| args += a }
17
+ end
18
+ end
19
+ alias_method Pagy::DEFAULT[:searchkick_pagy_search], :pagy_searchkick
20
+ end
7
21
 
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}
22
+ # Additions for the Pagy class
23
+ module Pagy
24
+ # Create a Pagy object from a Searchkick::Results object
25
+ def new_from_searchkick(results, vars = {})
26
+ vars[:items] = results.options[:per_page]
27
+ vars[:page] = results.options[:page]
28
+ vars[:count] = results.total_count
29
+ new(vars)
15
30
  end
16
31
  end
17
- alias_method VARS[:searchkick_search_method], :pagy_searchkick
18
- end
19
32
 
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
33
+ # Add specialized backend methods to paginate Searchkick::Results
34
+ module Backend
35
+ private
27
36
 
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
37
+ # Return Pagy object and results
38
+ def pagy_searchkick(pagy_search_args, vars = {})
39
+ model, term, options, block, *called = pagy_search_args
40
+ vars = pagy_searchkick_get_vars(nil, vars)
41
+ options[:per_page] = vars[:items]
42
+ options[:page] = vars[:page]
43
+ results = model.send(DEFAULT[:searchkick_search], term, **options, &block)
44
+ vars[:count] = results.total_count
48
45
 
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
46
+ pagy = ::Pagy.new(vars)
47
+ # with :last_page overflow we need to re-run the method in order to get the hits
48
+ return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page)) \
49
+ if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
50
+
51
+ [pagy, called.empty? ? results : results.send(*called)]
52
+ end
57
53
 
54
+ # Sub-method called only by #pagy_searchkick: here for easy customization of variables by overriding
55
+ # the _collection argument is not available when the method is called
56
+ def pagy_searchkick_get_vars(_collection, vars)
57
+ pagy_set_items_from_params(vars) if defined?(ItemsExtra)
58
+ vars[:items] ||= DEFAULT[:items]
59
+ vars[:page] ||= (params[vars[:page_param] || DEFAULT[:page_param]] || 1).to_i
60
+ vars
61
+ end
62
+ end
58
63
  end
64
+ Searchkick = SearchkickExtra::Searchkick
65
+ extend SearchkickExtra::Pagy
66
+ Backend.prepend SearchkickExtra::Backend
59
67
  end