pagy 8.6.3 → 9.3.4

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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/apps/calendar.ru +119 -127
  4. data/apps/demo.ru +274 -260
  5. data/apps/index.rb +7 -0
  6. data/apps/keyset_ar.ru +227 -0
  7. data/apps/keyset_s.ru +219 -0
  8. data/apps/rails.ru +25 -20
  9. data/apps/repro.ru +108 -103
  10. data/bin/pagy +18 -20
  11. data/config/pagy.rb +19 -15
  12. data/javascripts/pagy.min.js +2 -2
  13. data/javascripts/pagy.min.js.map +3 -3
  14. data/javascripts/pagy.mjs +2 -2
  15. data/lib/pagy/b64.rb +33 -0
  16. data/lib/pagy/backend.rb +20 -20
  17. data/lib/pagy/calendar/day.rb +2 -2
  18. data/lib/pagy/calendar/month.rb +2 -2
  19. data/lib/pagy/calendar/quarter.rb +2 -2
  20. data/lib/pagy/calendar/unit.rb +7 -10
  21. data/lib/pagy/calendar/week.rb +2 -2
  22. data/lib/pagy/calendar/year.rb +2 -2
  23. data/lib/pagy/calendar.rb +15 -13
  24. data/lib/pagy/countless.rb +10 -14
  25. data/lib/pagy/extras/arel.rb +3 -11
  26. data/lib/pagy/extras/array.rb +5 -10
  27. data/lib/pagy/extras/bootstrap.rb +5 -5
  28. data/lib/pagy/extras/bulma.rb +10 -7
  29. data/lib/pagy/extras/calendar.rb +13 -17
  30. data/lib/pagy/extras/countless.rb +8 -13
  31. data/lib/pagy/extras/elasticsearch_rails.rb +16 -25
  32. data/lib/pagy/extras/gearbox.rb +18 -18
  33. data/lib/pagy/extras/headers.rb +25 -24
  34. data/lib/pagy/extras/i18n.rb +1 -1
  35. data/lib/pagy/extras/js_tools.rb +6 -6
  36. data/lib/pagy/extras/jsonapi.rb +30 -21
  37. data/lib/pagy/extras/keyset.rb +30 -0
  38. data/lib/pagy/extras/limit.rb +63 -0
  39. data/lib/pagy/extras/meilisearch.rb +9 -17
  40. data/lib/pagy/extras/metadata.rb +3 -3
  41. data/lib/pagy/extras/overflow.rb +9 -9
  42. data/lib/pagy/extras/pagy.rb +16 -16
  43. data/lib/pagy/extras/searchkick.rb +9 -17
  44. data/lib/pagy/extras/size.rb +1 -1
  45. data/lib/pagy/extras/standalone.rb +6 -6
  46. data/lib/pagy/extras/trim.rb +3 -3
  47. data/lib/pagy/frontend.rb +32 -33
  48. data/lib/pagy/i18n.rb +3 -2
  49. data/lib/pagy/keyset/active_record.rb +38 -0
  50. data/lib/pagy/keyset/sequel.rb +51 -0
  51. data/lib/pagy/keyset.rb +118 -0
  52. data/lib/pagy/shared_methods.rb +26 -0
  53. data/lib/pagy/url_helpers.rb +5 -5
  54. data/lib/pagy.rb +53 -67
  55. data/locales/ar.yml +1 -1
  56. data/locales/be.yml +1 -1
  57. data/locales/bg.yml +1 -1
  58. data/locales/bs.yml +1 -1
  59. data/locales/ca.yml +1 -1
  60. data/locales/ckb.yml +1 -1
  61. data/locales/cs.yml +1 -1
  62. data/locales/da.yml +1 -1
  63. data/locales/de.yml +1 -1
  64. data/locales/dz.yml +17 -0
  65. data/locales/en.yml +1 -1
  66. data/locales/es.yml +1 -1
  67. data/locales/fr.yml +1 -1
  68. data/locales/hr.yml +1 -1
  69. data/locales/id.yml +1 -1
  70. data/locales/it.yml +1 -1
  71. data/locales/ja.yml +1 -1
  72. data/locales/km.yml +1 -1
  73. data/locales/ko.yml +1 -1
  74. data/locales/nb.yml +1 -1
  75. data/locales/nl.yml +1 -1
  76. data/locales/nn.yml +1 -1
  77. data/locales/pl.yml +1 -1
  78. data/locales/pt-BR.yml +1 -1
  79. data/locales/pt.yml +1 -1
  80. data/locales/ru.yml +1 -1
  81. data/locales/sr.yml +1 -1
  82. data/locales/sv-SE.yml +1 -1
  83. data/locales/sv.yml +1 -1
  84. data/locales/sw.yml +3 -1
  85. data/locales/ta.yml +3 -1
  86. data/locales/tr.yml +1 -1
  87. data/locales/uk.yml +1 -1
  88. data/locales/vi.yml +1 -1
  89. data/locales/zh-CN.yml +7 -9
  90. data/locales/zh-HK.yml +7 -9
  91. data/locales/zh-TW.yml +7 -9
  92. metadata +14 -27
  93. data/apps/tmp/calendar.sqlite3 +0 -0
  94. data/apps/tmp/calendar.sqlite3-shm +0 -0
  95. data/apps/tmp/calendar.sqlite3-wal +0 -0
  96. data/apps/tmp/local_secret.txt +0 -1
  97. data/apps/tmp/pagy-keyset.sqlite3 +0 -0
  98. data/apps/tmp/pagy-keyset.sqlite3-shm +0 -0
  99. data/apps/tmp/pagy-keyset.sqlite3-wal +0 -0
  100. data/javascripts/pagy-module.js +0 -100
  101. data/javascripts/pagy.js +0 -4
  102. data/lib/pagy/extras/foundation.rb +0 -95
  103. data/lib/pagy/extras/items.rb +0 -64
  104. data/lib/pagy/extras/materialize.rb +0 -100
  105. data/lib/pagy/extras/semantic.rb +0 -94
  106. data/lib/pagy/extras/uikit.rb +0 -98
@@ -18,16 +18,25 @@ class Pagy # :nodoc:
18
18
 
19
19
  # Module overriding Backend
20
20
  module BackendOverride
21
- private
22
-
23
21
  include UrlHelpers
24
22
 
23
+ private(*UrlHelpers.instance_methods)
24
+
25
+ private
26
+
25
27
  # Return the jsonapi links
26
28
  def pagy_jsonapi_links(pagy, **opts)
27
- { first: pagy_url_for(pagy, 1, **opts),
28
- last: pagy_url_for(pagy, pagy.last, **opts),
29
- prev: pagy.prev ? pagy_url_for(pagy, pagy.prev, **opts) : nil,
30
- next: pagy.next ? pagy_url_for(pagy, pagy.next, **opts) : nil }
29
+ if defined?(::Pagy::Keyset) && pagy.is_a?(Keyset)
30
+ { first: pagy_url_for(pagy, nil, **opts),
31
+ last: nil,
32
+ prev: nil,
33
+ next: pagy.next ? pagy_url_for(pagy, pagy.next, **opts) : nil }
34
+ else
35
+ { first: pagy_url_for(pagy, 1, **opts),
36
+ last: pagy_url_for(pagy, pagy.last, **opts),
37
+ prev: pagy.prev ? pagy_url_for(pagy, pagy.prev, **opts) : nil,
38
+ next: pagy.next ? pagy_url_for(pagy, pagy.next, **opts) : nil }
39
+ end
31
40
  end
32
41
 
33
42
  # Should skip the jsonapi
@@ -38,40 +47,40 @@ class Pagy # :nodoc:
38
47
  end
39
48
 
40
49
  # Override the Backend method
41
- def pagy_get_page(vars)
42
- return super if pagy_skip_jsonapi?(vars)
43
- return 1 if params[:page].nil?
50
+ def pagy_get_page(vars, force_integer: true)
51
+ return super if pagy_skip_jsonapi?(vars) || params[:page].nil?
44
52
 
45
- [params[:page][vars[:page_param] || DEFAULT[:page_param]].to_i, 1].max
53
+ page = params[:page][vars[:page_param] || DEFAULT[:page_param]]
54
+ force_integer ? (page || 1).to_i : page
46
55
  end
47
56
  end
48
57
  Backend.prepend BackendOverride
49
58
 
50
- # Module overriding ItemsExtra
51
- module ItemsExtraOverride
59
+ # Module overriding LimitExtra
60
+ module LimitExtraOverride
52
61
  private
53
62
 
54
- # Override the ItemsExtra::Backend method
55
- def pagy_get_items_size(vars)
63
+ # Override the LimitExtra::Backend method
64
+ def pagy_get_limit_param(vars)
56
65
  return super if pagy_skip_jsonapi?(vars)
57
- return if params[:page].nil?
66
+ return unless params[:page]
58
67
 
59
- params[:page][vars[:items_param] || DEFAULT[:items_param]]
68
+ params[:page][vars[:limit_param] || DEFAULT[:limit_param]]
60
69
  end
61
70
  end
62
71
  # :nocov:
63
- ItemsExtra::BackendAddOn.prepend ItemsExtraOverride if defined?(ItemsExtra::BackendAddOn)
72
+ LimitExtra::BackendAddOn.prepend LimitExtraOverride if defined?(::Pagy::LimitExtra::BackendAddOn)
64
73
  # :nocov:
65
74
 
66
75
  # Module overriding UrlHelper
67
76
  module UrlHelperOverride
68
77
  # Override UrlHelper method
69
- def pagy_set_query_params(page, vars, params)
78
+ def pagy_set_query_params(page, vars, query_params)
70
79
  return super unless vars[:jsonapi]
71
80
 
72
- params['page'] ||= {}
73
- params['page'][vars[:page_param].to_s] = page
74
- params['page'][vars[:items_param].to_s] = vars[:items] if vars[:items_extra]
81
+ query_params['page'] ||= {}
82
+ query_params['page'][vars[:page_param].to_s] = page
83
+ query_params['page'][vars[:limit_param].to_s] = vars[:limit] if vars[:limit_extra]
75
84
  end
76
85
  end
77
86
  UrlHelpers.prepend UrlHelperOverride
@@ -0,0 +1,30 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/keyset
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../keyset'
5
+
6
+ class Pagy # :nodoc:
7
+ # Add keyset pagination
8
+ module KeysetExtra
9
+ private
10
+
11
+ # Return Pagy::Keyset object and paginated records
12
+ def pagy_keyset(set, **vars)
13
+ vars[:page] ||= pagy_get_page(vars, force_integer: false) # allow nil
14
+ vars[:limit] ||= pagy_get_limit(vars)
15
+ pagy = Keyset.new(set, **vars)
16
+ [pagy, pagy.records]
17
+ end
18
+
19
+ # Return the URL string for the first page
20
+ def pagy_keyset_first_url(pagy, **vars)
21
+ pagy_url_for(pagy, nil, **vars)
22
+ end
23
+
24
+ # Return the URL string for the next page or nil
25
+ def pagy_keyset_next_url(pagy, **vars)
26
+ pagy_url_for(pagy, pagy.next, **vars) if pagy.next
27
+ end
28
+ end
29
+ Backend.prepend KeysetExtra
30
+ end
@@ -0,0 +1,63 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/limit
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'js_tools'
5
+
6
+ class Pagy # :nodoc:
7
+ DEFAULT[:limit_param] = :limit
8
+ DEFAULT[:limit_max] = 100
9
+ DEFAULT[:limit_extra] = true # extra enabled by default
10
+
11
+ # Allow the client to request a custom limit per page with an optional selector UI
12
+ module LimitExtra
13
+ # Additions for the Backend module
14
+ module BackendAddOn
15
+ private
16
+
17
+ # Set the limit variable considering the params and other pagy variables
18
+ def pagy_get_limit(vars)
19
+ return super unless vars.key?(:limit_extra) ? vars[:limit_extra] : DEFAULT[:limit_extra] # :limit_extra is false
20
+ return super unless (limit_count = pagy_get_limit_param(vars)) # no limit from request params
21
+
22
+ vars[:limit] = [limit_count.to_i, vars.key?(:limit_max) ? vars[:limit_max] : DEFAULT[:limit_max]].compact.min
23
+ end
24
+
25
+ # Get the limit count from the params
26
+ # Overridable by the jsonapi extra
27
+ def pagy_get_limit_param(vars)
28
+ params[vars[:limit_param] || DEFAULT[:limit_param]]
29
+ end
30
+ end
31
+ Backend.prepend LimitExtra::BackendAddOn
32
+
33
+ # Additions for the Frontend module
34
+ module FrontendAddOn
35
+ LIMIT_TOKEN = '__pagy_limit__'
36
+
37
+ # Return the limit selector HTML. For example "Show [20] items per page"
38
+ def pagy_limit_selector_js(pagy, id: nil, item_name: nil)
39
+ return '' unless pagy.vars[:limit_extra]
40
+
41
+ id = %( id="#{id}") if id
42
+ vars = pagy.vars
43
+ limit = vars[:limit]
44
+ vars[:limit] = LIMIT_TOKEN
45
+ url_token = pagy_url_for(pagy, PAGE_TOKEN)
46
+ vars[:limit] = limit # restore the limit
47
+
48
+ limit_input = %(<input name="limit" type="number" min="1" max="#{vars[:limit_max]}" value="#{
49
+ limit}" style="padding: 0; text-align: center; width: #{limit.to_s.length + 1}rem;">#{JSTools::A_TAG})
50
+
51
+ %(<span#{id} class="pagy limit-selector-js" #{
52
+ pagy_data(pagy, :selector, pagy.from, url_token)
53
+ }><label>#{
54
+ pagy_t('pagy.limit_selector_js',
55
+ item_name: item_name || pagy_t('pagy.item_name', count: limit),
56
+ limit_input:,
57
+ count: limit)
58
+ }</label></span>)
59
+ end
60
+ end
61
+ Frontend.prepend LimitExtra::FrontendAddOn
62
+ end
63
+ end
@@ -20,12 +20,12 @@ class Pagy # :nodoc:
20
20
  # Extension for the Pagy class
21
21
  module PagyExtension
22
22
  # Create a Pagy object from a Meilisearch results
23
- def new_from_meilisearch(results, vars = {})
24
- vars[:items] = results.raw_answer['hitsPerPage']
23
+ def new_from_meilisearch(results, **vars)
24
+ vars[:limit] = results.raw_answer['hitsPerPage']
25
25
  vars[:page] = results.raw_answer['page']
26
26
  vars[:count] = results.raw_answer['totalHits']
27
27
 
28
- new(vars)
28
+ new(**vars)
29
29
  end
30
30
  end
31
31
  Pagy.extend PagyExtension
@@ -35,30 +35,22 @@ class Pagy # :nodoc:
35
35
  private
36
36
 
37
37
  # Return Pagy object and results
38
- def pagy_meilisearch(pagy_search_args, vars = {})
38
+ def pagy_meilisearch(pagy_search_args, **vars)
39
+ vars[:page] ||= pagy_get_page(vars)
40
+ vars[:limit] ||= pagy_get_limit(vars)
39
41
  model, term, options = pagy_search_args
40
- vars = pagy_meilisearch_get_vars(nil, vars)
41
- options[:hits_per_page] = vars[:items]
42
+ options[:hits_per_page] = vars[:limit]
42
43
  options[:page] = vars[:page]
43
44
  results = model.send(:ms_search, term, options)
44
45
  vars[:count] = results.raw_answer['totalHits']
45
46
 
46
- pagy = ::Pagy.new(vars)
47
+ pagy = ::Pagy.new(**vars)
47
48
  # with :last_page overflow we need to re-run the method in order to get the hits
48
- return pagy_meilisearch(pagy_search_args, vars.merge(page: pagy.page)) \
49
+ return pagy_meilisearch(pagy_search_args, **vars, page: pagy.page) \
49
50
  if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
50
51
 
51
52
  [pagy, results]
52
53
  end
53
-
54
- # Sub-method called only by #pagy_meilisearch: here for easy customization of variables by overriding.
55
- # The _collection argument is not available when the method is called.
56
- def pagy_meilisearch_get_vars(_collection, vars)
57
- pagy_set_items_from_params(vars) if defined?(ItemsExtra)
58
- vars[:items] ||= DEFAULT[:items]
59
- vars[:page] ||= pagy_get_page(vars)
60
- vars
61
- end
62
54
  end
63
55
  Backend.prepend BackendAddOn
64
56
  end
@@ -5,7 +5,7 @@ require_relative '../url_helpers'
5
5
 
6
6
  class Pagy # :nodoc:
7
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 ]
8
+ count page limit vars pages last in from to prev next series ]
9
9
 
10
10
  # Add a specialized backend method for pagination metadata
11
11
  module MetadataExtra
@@ -17,8 +17,8 @@ class Pagy # :nodoc:
17
17
  def pagy_metadata(pagy, absolute: nil)
18
18
  scaffold_url = pagy_url_for(pagy, PAGE_TOKEN, absolute:)
19
19
  {}.tap do |metadata|
20
- keys = if defined?(Calendar::Unit) && pagy.is_a?(Calendar::Unit)
21
- pagy.vars[:metadata] - %i[count items]
20
+ keys = if defined?(::Pagy::Calendar::Unit) && pagy.is_a?(Calendar::Unit)
21
+ pagy.vars[:metadata] - %i[count limit]
22
22
  else
23
23
  pagy.vars[:metadata]
24
24
  end
@@ -14,7 +14,7 @@ class Pagy # :nodoc:
14
14
  end
15
15
 
16
16
  # Add rescue clause for different behaviors
17
- def initialize(vars)
17
+ def initialize(**vars)
18
18
  @overflow ||= false # still true if :last_page re-run the method after an overflow
19
19
  super
20
20
  rescue OverflowError
@@ -24,14 +24,14 @@ class Pagy # :nodoc:
24
24
  raise # same as without the extra
25
25
  when :last_page
26
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
27
+ initialize(**vars, page: @last) # re-run with the last page
28
28
  @vars[:page] = requested_page # restore the requested page
29
29
  when :empty_page
30
- @offset = @items = @in = @from = @to = 0 # vars relative to the actual page
31
- if defined?(Calendar::Unit) \
30
+ @in = @from = @to = 0 # vars relative to the actual page
31
+ if defined?(::Pagy::Calendar::Unit) \
32
32
  && is_a?(Calendar::Unit) # only for Calendar::Units instances
33
33
  edge = @order == :asc ? @final : @initial # get the edge of the overflow side (neat, but any time would do)
34
- @from = @to = edge # set both to the edge utc time (a >=&&< query will get no records)
34
+ @from = @to = edge # set both to the edge time (a >=&&< query will get no records)
35
35
  end
36
36
  @prev = @last # prev relative to the actual page
37
37
  extend Series # special series for :empty_page
@@ -52,12 +52,12 @@ class Pagy # :nodoc:
52
52
  end
53
53
  end
54
54
  Pagy.prepend PagyOverride
55
- Pagy::Calendar::Unit.prepend PagyOverride if defined?(Calendar::Unit)
55
+ Pagy::Calendar::Unit.prepend PagyOverride if defined?(::Pagy::Calendar::Unit)
56
56
 
57
57
  # Support for Pagy::Countless class
58
58
  module CountlessOverride
59
59
  # Add rescue clause for different behaviors
60
- def finalize(items)
60
+ def finalize(fetched_size)
61
61
  @overflow = false
62
62
  super
63
63
  rescue OverflowError
@@ -66,7 +66,7 @@ class Pagy # :nodoc:
66
66
  when :exception
67
67
  raise # same as without the extra
68
68
  when :empty_page
69
- @offset = @items = @from = @to = 0 # vars relative to the actual page
69
+ @offset = @limit = @from = @to = 0 # vars relative to the actual page
70
70
  @vars[:size] = 0 # no page in the series
71
71
  self
72
72
  else
@@ -75,7 +75,7 @@ class Pagy # :nodoc:
75
75
  end
76
76
  end
77
77
  # :nocov:
78
- Pagy::Countless.prepend CountlessOverride if defined?(Countless)
78
+ Pagy::Countless.prepend CountlessOverride if defined?(::Pagy::Countless)
79
79
  # :nocov:
80
80
  end
81
81
  end
@@ -12,7 +12,7 @@ class Pagy # :nodoc:
12
12
  def pagy_nav_js(pagy, id: nil, aria_label: nil, **vars)
13
13
  sequels = pagy.sequels(**vars)
14
14
  id = %( id="#{id}") if id
15
- a = pagy_anchor(pagy)
15
+ a = pagy_anchor(pagy, **vars)
16
16
  tokens = { 'before' => prev_a(pagy, a),
17
17
  'a' => a.(PAGE_TOKEN, LABEL_TOKEN),
18
18
  'current' => %(<a class="current" role="link" aria-current="page" aria-disabled="true">#{
@@ -27,9 +27,9 @@ class Pagy # :nodoc:
27
27
  end
28
28
 
29
29
  # Javascript combo pagination: it returns a nav with a data-pagy attribute used by the pagy.js file
30
- def pagy_combo_nav_js(pagy, id: nil, aria_label: nil)
30
+ def pagy_combo_nav_js(pagy, id: nil, aria_label: nil, **vars)
31
31
  id = %( id="#{id}") if id
32
- a = pagy_anchor(pagy)
32
+ a = pagy_anchor(pagy, **vars)
33
33
  pages = pagy.pages
34
34
 
35
35
  page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
@@ -37,7 +37,7 @@ class Pagy # :nodoc:
37
37
 
38
38
  %(<nav#{id} class="pagy combo-nav-js" #{
39
39
  nav_aria_label(pagy, aria_label:)} #{
40
- pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))}>#{
40
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN, **vars))}>#{
41
41
  prev_a(pagy, a)
42
42
  }<label>#{
43
43
  pagy_t('pagy.combo_nav_js', page_input:, pages:)
@@ -47,35 +47,35 @@ class Pagy # :nodoc:
47
47
  end
48
48
 
49
49
  # Return the previous page URL string or nil
50
- def pagy_prev_url(pagy, absolute: false)
51
- pagy_url_for(pagy, pagy.prev, absolute:) if pagy.prev
50
+ def pagy_prev_url(pagy, **vars)
51
+ pagy_url_for(pagy, pagy.prev, **vars) if pagy.prev
52
52
  end
53
53
 
54
54
  # Return the next page URL string or nil
55
- def pagy_next_url(pagy, absolute: false)
56
- pagy_url_for(pagy, pagy.next, absolute:) if pagy.next
55
+ def pagy_next_url(pagy, **vars)
56
+ pagy_url_for(pagy, pagy.next, **vars) if pagy.next
57
57
  end
58
58
 
59
59
  # Return the enabled/disabled previous page anchor tag
60
- def pagy_prev_a(pagy, text: pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'))
61
- a = pagy_anchor(pagy)
60
+ def pagy_prev_a(pagy, text: pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'), **vars)
61
+ a = pagy_anchor(pagy, **vars)
62
62
  prev_a(pagy, a, text:, aria_label:)
63
63
  end
64
64
 
65
65
  # Return the enabled/disabled next page anchor tag
66
- def pagy_next_a(pagy, text: pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.next'))
67
- a = pagy_anchor(pagy)
66
+ def pagy_next_a(pagy, text: pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.next'), **vars)
67
+ a = pagy_anchor(pagy, **vars)
68
68
  next_a(pagy, a, text:, aria_label:)
69
69
  end
70
70
 
71
71
  # Conditionally return the previous page link tag
72
- def pagy_prev_link(pagy, absolute: false)
73
- %(<link href="#{pagy_url_for(pagy, pagy.prev, absolute:)}"/>) if pagy.prev
72
+ def pagy_prev_link(pagy, **vars)
73
+ %(<link href="#{pagy_url_for(pagy, pagy.prev, **vars)}"/>) if pagy.prev
74
74
  end
75
75
 
76
76
  # Conditionally return the next page link tag
77
- def pagy_next_link(pagy, absolute: false)
78
- %(<link href="#{pagy_url_for(pagy, pagy.next, absolute:)}"/>) if pagy.next
77
+ def pagy_next_link(pagy, **vars)
78
+ %(<link href="#{pagy_url_for(pagy, pagy.next, **vars)}"/>) if pagy.next
79
79
  end
80
80
  end
81
81
  Frontend.prepend PagyExtra
@@ -23,11 +23,11 @@ class Pagy # :nodoc:
23
23
  # Additions for the Pagy class
24
24
  module PagyExtension
25
25
  # Create a Pagy object from a Searchkick::Results object
26
- def new_from_searchkick(results, vars = {})
27
- vars[:items] = results.options[:per_page]
26
+ def new_from_searchkick(results, **vars)
27
+ vars[:limit] = results.options[:per_page]
28
28
  vars[:page] = results.options[:page]
29
29
  vars[:count] = results.total_count
30
- new(vars)
30
+ new(**vars)
31
31
  end
32
32
  end
33
33
  Pagy.extend PagyExtension
@@ -37,30 +37,22 @@ class Pagy # :nodoc:
37
37
  private
38
38
 
39
39
  # Return Pagy object and results
40
- def pagy_searchkick(pagy_search_args, vars = {})
40
+ def pagy_searchkick(pagy_search_args, **vars)
41
+ vars[:page] ||= pagy_get_page(vars)
42
+ vars[:limit] ||= pagy_get_limit(vars)
41
43
  model, term, options, block, *called = pagy_search_args
42
- vars = pagy_searchkick_get_vars(nil, vars)
43
- options[:per_page] = vars[:items]
44
+ options[:per_page] = vars[:limit]
44
45
  options[:page] = vars[:page]
45
46
  results = model.send(DEFAULT[:searchkick_search], term, **options, &block)
46
47
  vars[:count] = results.total_count
47
48
 
48
- pagy = ::Pagy.new(vars)
49
+ pagy = ::Pagy.new(**vars)
49
50
  # with :last_page overflow we need to re-run the method in order to get the hits
50
- return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page)) \
51
+ return pagy_searchkick(pagy_search_args, **vars, page: pagy.page) \
51
52
  if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
52
53
 
53
54
  [pagy, called.empty? ? results : results.send(*called)]
54
55
  end
55
-
56
- # Sub-method called only by #pagy_searchkick: here for easy customization of variables by overriding
57
- # the _collection argument is not available when the method is called
58
- def pagy_searchkick_get_vars(_collection, vars)
59
- pagy_set_items_from_params(vars) if defined?(ItemsExtra)
60
- vars[:items] ||= DEFAULT[:items]
61
- vars[:page] ||= pagy_get_page(vars)
62
- vars
63
- end
64
56
  end
65
57
  Backend.prepend BackendAddOn
66
58
  end
@@ -5,7 +5,7 @@ class Pagy # :nodoc:
5
5
  # Implement the legacy bar using the array size.
6
6
  # Unless you have very specific requirements, use the faster and better looking default bar.
7
7
  module SizeExtra
8
- # Setup @items based on the :gearbox_items variable
8
+ # Implements the old series algorithm
9
9
  def series(size: @vars[:size], **_)
10
10
  return super unless size.is_a?(Array)
11
11
  return [] if size == []
@@ -12,10 +12,6 @@ class Pagy # :nodoc:
12
12
  module QueryUtils
13
13
  module_function
14
14
 
15
- def escape(str)
16
- URI.encode_www_form_component(str)
17
- end
18
-
19
15
  def build_nested_query(value, prefix = nil)
20
16
  case value
21
17
  when Array
@@ -32,13 +28,17 @@ class Pagy # :nodoc:
32
28
  "#{escape(prefix)}=#{escape(value)}"
33
29
  end
34
30
  end
31
+
32
+ def escape(str)
33
+ URI.encode_www_form_component(str)
34
+ end
35
35
  end
36
36
  # :nocov:
37
37
 
38
38
  # Return the URL for the page. If there is no pagy.vars[:url]
39
39
  # it works exactly as the regular #pagy_url_for, relying on the params method and Rack.
40
40
  # If there is a defined pagy.vars[:url] variable it does not need the params method nor Rack.
41
- def pagy_url_for(pagy, page, absolute: false, **_)
41
+ def pagy_url_for(pagy, page, fragment: nil, **_)
42
42
  return super unless pagy.vars[:url]
43
43
 
44
44
  vars = pagy.vars
@@ -46,7 +46,7 @@ class Pagy # :nodoc:
46
46
  pagy_set_query_params(page, vars, params)
47
47
  params = vars[:params].(params) if vars[:params].is_a?(Proc)
48
48
  query_string = "?#{QueryUtils.build_nested_query(params)}"
49
- "#{vars[:url]}#{query_string}#{vars[:fragment]}"
49
+ "#{vars[:url]}#{query_string}#{fragment}"
50
50
  end
51
51
  end
52
52
  UrlHelpers.prepend StandaloneExtra
@@ -6,9 +6,9 @@ class Pagy # :nodoc:
6
6
 
7
7
  # Remove the page=1 param from the first page link
8
8
  module TrimExtra
9
- # Override the original pagy_a_proc.
9
+ # Override the original pagy_anchor.
10
10
  # Call the pagy_trim method for page 1 if the trim_extra is enabled
11
- def pagy_anchor(pagy)
11
+ def pagy_anchor(pagy, **_)
12
12
  a_proc = super
13
13
  return a_proc unless pagy.vars[:trim_extra]
14
14
 
@@ -20,7 +20,7 @@ class Pagy # :nodoc:
20
20
  end
21
21
  end
22
22
 
23
- # Remove the the :page_param param from the first page anchor
23
+ # Remove the :page_param param from the first page anchor
24
24
  def pagy_trim(pagy, a)
25
25
  a.sub!(/[?&]#{pagy.vars[:page_param]}=1\b(?!&)|\b#{pagy.vars[:page_param]}=1&/, '')
26
26
  end
data/lib/pagy/frontend.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # See Pagy::Frontend API documentation: https://ddnexus.github.io/pagy/docs/api/frontend
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative 'url_helpers'
5
4
  require_relative 'i18n'
5
+ require_relative 'url_helpers'
6
6
 
7
7
  class Pagy
8
8
  # Used for search and replace, hardcoded also in the pagy.js file
@@ -14,26 +14,17 @@ class Pagy
14
14
  module Frontend
15
15
  include UrlHelpers
16
16
 
17
- # Generic pagination: it returns the html with the series of links to the pages
18
- def pagy_nav(pagy, id: nil, aria_label: nil, **vars)
19
- id = %( id="#{id}") if id
20
- a = pagy_anchor(pagy)
21
-
22
- html = %(<nav#{id} class="pagy nav" #{nav_aria_label(pagy, aria_label:)}>#{
23
- prev_a(pagy, a)})
24
- pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
25
- html << case item
26
- when Integer
27
- a.(item)
28
- when String
29
- %(<a role="link" aria-disabled="true" aria-current="page" class="current">#{pagy.label_for(item)}</a>)
30
- when :gap
31
- %(<a role="link" aria-disabled="true" class="gap">#{pagy_t('pagy.gap')}</a>)
32
- else
33
- raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
34
- end
17
+ # Return a performance optimized lambda to generate the HTML anchor element (a tag)
18
+ # Benchmarked on a 20 link nav: it is ~22x faster and uses ~18x less memory than rails' link_to
19
+ def pagy_anchor(pagy, anchor_string: nil, **vars)
20
+ anchor_string &&= %( #{anchor_string})
21
+ left, right = %(<a#{anchor_string} href="#{pagy_url_for(pagy, PAGE_TOKEN, **vars)}").split(PAGE_TOKEN, 2)
22
+ # lambda used by all the helpers
23
+ lambda do |page, text = pagy.label_for(page), classes: nil, aria_label: nil|
24
+ classes = %( class="#{classes}") if classes
25
+ aria_label = %( aria-label="#{aria_label}") if aria_label
26
+ %(#{left}#{page}#{right}#{classes}#{aria_label}>#{text}</a>)
35
27
  end
36
- html << %(#{next_a(pagy, a)}</nav>)
37
28
  end
38
29
 
39
30
  # Return examples: "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total"
@@ -54,24 +45,32 @@ class Pagy
54
45
  }</span>)
55
46
  end
56
47
 
57
- # Return a performance optimized lambda to generate the HTML anchor element (a tag)
58
- # Benchmarked on a 20 link nav: it is ~22x faster and uses ~18x less memory than rails' link_to
59
- def pagy_anchor(pagy)
60
- a_string = pagy.vars[:anchor_string]
61
- a_string = %( #{a_string}) if a_string
62
- left, right = %(<a#{a_string} href="#{pagy_url_for(pagy, PAGE_TOKEN)}").split(PAGE_TOKEN, 2)
63
- # lambda used by all the helpers
64
- lambda do |page, text = pagy.label_for(page), classes: nil, aria_label: nil|
65
- classes = %( class="#{classes}") if classes
66
- aria_label = %( aria-label="#{aria_label}") if aria_label
67
- %(#{left}#{page}#{right}#{classes}#{aria_label}>#{text}</a>)
48
+ # Generic pagination: it returns the html with the series of links to the pages
49
+ def pagy_nav(pagy, id: nil, aria_label: nil, **vars)
50
+ id = %( id="#{id}") if id
51
+ a = pagy_anchor(pagy, **vars)
52
+
53
+ html = %(<nav#{id} class="pagy nav" #{nav_aria_label(pagy, aria_label:)}>#{
54
+ prev_a(pagy, a)})
55
+ pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
56
+ html << case item
57
+ when Integer
58
+ a.(item)
59
+ when String
60
+ %(<a role="link" aria-disabled="true" aria-current="page" class="current">#{pagy.label_for(item)}</a>)
61
+ when :gap
62
+ %(<a role="link" aria-disabled="true" class="gap">#{pagy_t('pagy.gap')}</a>)
63
+ else
64
+ raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
65
+ end
68
66
  end
67
+ html << %(#{next_a(pagy, a)}</nav>)
69
68
  end
70
69
 
71
70
  # Similar to I18n.t: just ~18x faster using ~10x less memory
72
71
  # (@pagy_locale explicitly initialized in order to avoid warning)
73
- def pagy_t(key, opts = {})
74
- Pagy::I18n.translate(@pagy_locale ||= nil, key, opts)
72
+ def pagy_t(key, **opts)
73
+ Pagy::I18n.translate(@pagy_locale ||= nil, key, **opts)
75
74
  end
76
75
 
77
76
  private
data/lib/pagy/i18n.rb CHANGED
@@ -113,12 +113,13 @@ class Pagy
113
113
  hash['zh-CN'] = RULE[:other]
114
114
  hash['zh-HK'] = RULE[:other]
115
115
  hash['zh-TW'] = RULE[:other]
116
+ hash['dz'] = RULE[:other]
116
117
  end.freeze
117
118
  end
118
119
 
119
120
  # Stores the i18n DATA structure for each loaded locale
120
121
  # default on the first locale DATA
121
- DATA = Hash.new { |hash, _| hash.first[1] }
122
+ DATA = Hash.new { |hash,| hash.first[1] }
122
123
 
123
124
  private
124
125
 
@@ -154,7 +155,7 @@ class Pagy
154
155
  end
155
156
 
156
157
  # Translate and pluralize the key with the locale DATA
157
- def translate(locale, key, opts = {})
158
+ def translate(locale, key, **opts)
158
159
  data, pluralize = DATA[locale]
159
160
  translation = data[key] || (opts[:count] && data[key += ".#{pluralize.call(opts[:count])}"]) \
160
161
  or return %([translation missing: "#{key}"])