pagy 4.11.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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