pagy 7.0.11 → 43.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/apps/calendar.ru +741 -0
  4. data/apps/demo.ru +513 -0
  5. data/apps/enable_rails_page_segment.rb +54 -0
  6. data/apps/index.rb +9 -0
  7. data/apps/keynav+root_key.ru +316 -0
  8. data/apps/keynav.ru +255 -0
  9. data/apps/keyset.ru +219 -0
  10. data/apps/keyset_sequel.ru +212 -0
  11. data/apps/rails.ru +216 -0
  12. data/apps/repro.ru +185 -0
  13. data/bin/pagy +5 -0
  14. data/config/pagy.rb +46 -0
  15. data/javascripts/ai_widget.js +90 -0
  16. data/javascripts/pagy.js +168 -0
  17. data/javascripts/pagy.min.js +2 -0
  18. data/javascripts/pagy.mjs +161 -0
  19. data/javascripts/wand.js +1172 -0
  20. data/lib/pagy/classes/calendar/calendar.rb +101 -0
  21. data/lib/pagy/{calendar → classes/calendar}/day.rb +9 -12
  22. data/lib/pagy/{calendar → classes/calendar}/month.rb +7 -11
  23. data/lib/pagy/{calendar → classes/calendar}/quarter.rb +12 -16
  24. data/lib/pagy/classes/calendar/unit.rb +93 -0
  25. data/lib/pagy/{calendar → classes/calendar}/week.rb +7 -11
  26. data/lib/pagy/{calendar → classes/calendar}/year.rb +9 -9
  27. data/lib/pagy/classes/exceptions.rb +26 -0
  28. data/lib/pagy/classes/keyset/adapters/active_record.rb +50 -0
  29. data/lib/pagy/classes/keyset/adapters/sequel.rb +62 -0
  30. data/lib/pagy/classes/keyset/keynav.rb +85 -0
  31. data/lib/pagy/classes/keyset/keyset.rb +150 -0
  32. data/lib/pagy/classes/offset/countish.rb +17 -0
  33. data/lib/pagy/classes/offset/countless.rb +63 -0
  34. data/lib/pagy/classes/offset/offset.rb +63 -0
  35. data/lib/pagy/classes/offset/search.rb +34 -0
  36. data/lib/pagy/classes/request.rb +48 -0
  37. data/lib/pagy/cli.rb +122 -0
  38. data/lib/pagy/console.rb +5 -20
  39. data/lib/pagy/deprecated.rb +84 -0
  40. data/lib/pagy/modules/abilities/configurable.rb +37 -0
  41. data/lib/pagy/modules/abilities/countable.rb +23 -0
  42. data/lib/pagy/modules/abilities/linkable.rb +72 -0
  43. data/lib/pagy/modules/abilities/rangeable.rb +14 -0
  44. data/lib/pagy/modules/abilities/shiftable.rb +12 -0
  45. data/lib/pagy/modules/b64.rb +35 -0
  46. data/lib/pagy/modules/console.rb +33 -0
  47. data/lib/pagy/modules/i18n/i18n.rb +72 -0
  48. data/lib/pagy/modules/i18n/p11n/arabic.rb +30 -0
  49. data/lib/pagy/modules/i18n/p11n/east_slavic.rb +27 -0
  50. data/lib/pagy/modules/i18n/p11n/one_other.rb +15 -0
  51. data/lib/pagy/modules/i18n/p11n/one_upto_two_other.rb +15 -0
  52. data/lib/pagy/modules/i18n/p11n/other.rb +13 -0
  53. data/lib/pagy/modules/i18n/p11n/polish.rb +27 -0
  54. data/lib/pagy/modules/i18n/p11n/west_slavic.rb +22 -0
  55. data/lib/pagy/modules/i18n/p11n.rb +16 -0
  56. data/lib/pagy/modules/searcher.rb +20 -0
  57. data/lib/pagy/next.rb +25 -0
  58. data/lib/pagy/tasks/sync.rb +20 -0
  59. data/lib/pagy/toolbox/helpers/anchor_tags.rb +21 -0
  60. data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +28 -0
  61. data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +19 -0
  62. data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +32 -0
  63. data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +24 -0
  64. data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +25 -0
  65. data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +20 -0
  66. data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +31 -0
  67. data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +23 -0
  68. data/lib/pagy/toolbox/helpers/data_hash.rb +29 -0
  69. data/lib/pagy/toolbox/helpers/headers_hash.rb +30 -0
  70. data/lib/pagy/toolbox/helpers/info_tag.rb +30 -0
  71. data/lib/pagy/toolbox/helpers/input_nav_js.rb +22 -0
  72. data/lib/pagy/toolbox/helpers/limit_tag_js.rb +25 -0
  73. data/lib/pagy/toolbox/helpers/loaders.rb +55 -0
  74. data/lib/pagy/toolbox/helpers/page_url.rb +16 -0
  75. data/lib/pagy/toolbox/helpers/series_nav.rb +30 -0
  76. data/lib/pagy/toolbox/helpers/series_nav_js.rb +20 -0
  77. data/lib/pagy/toolbox/helpers/support/a_lambda.rb +36 -0
  78. data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +19 -0
  79. data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +10 -0
  80. data/lib/pagy/toolbox/helpers/support/series.rb +37 -0
  81. data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +19 -0
  82. data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +17 -0
  83. data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +42 -0
  84. data/lib/pagy/toolbox/helpers/urls_hash.rb +12 -0
  85. data/lib/pagy/toolbox/paginators/calendar.rb +34 -0
  86. data/lib/pagy/toolbox/paginators/countish.rb +38 -0
  87. data/lib/pagy/toolbox/paginators/countless.rb +22 -0
  88. data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +56 -0
  89. data/lib/pagy/toolbox/paginators/keynav_js.rb +26 -0
  90. data/lib/pagy/toolbox/paginators/keyset.rb +15 -0
  91. data/lib/pagy/toolbox/paginators/meilisearch.rb +34 -0
  92. data/lib/pagy/toolbox/paginators/method.rb +38 -0
  93. data/lib/pagy/toolbox/paginators/offset.rb +24 -0
  94. data/lib/pagy/toolbox/paginators/searchkick.rb +34 -0
  95. data/lib/pagy/toolbox/paginators/typesense_rails.rb +34 -0
  96. data/lib/pagy.rb +67 -131
  97. data/locales/ar.yml +32 -0
  98. data/locales/be.yml +28 -0
  99. data/locales/bg.yml +24 -0
  100. data/locales/bs.yml +28 -0
  101. data/locales/ca.yml +24 -0
  102. data/locales/ckb.yml +20 -0
  103. data/locales/cs.yml +26 -0
  104. data/locales/da.yml +24 -0
  105. data/locales/de.yml +24 -0
  106. data/locales/dz.yml +20 -0
  107. data/locales/en.yml +24 -0
  108. data/{lib/locales → locales}/es.yml +9 -6
  109. data/locales/fr.yml +24 -0
  110. data/locales/hr.yml +28 -0
  111. data/locales/id.yml +20 -0
  112. data/locales/it.yml +24 -0
  113. data/locales/ja.yml +20 -0
  114. data/locales/km.yml +20 -0
  115. data/locales/ko.yml +20 -0
  116. data/locales/nb.yml +24 -0
  117. data/locales/nl.yml +24 -0
  118. data/locales/nn.yml +24 -0
  119. data/locales/pl.yml +28 -0
  120. data/{lib/locales → locales}/pt-BR.yml +10 -7
  121. data/{lib/locales → locales}/pt.yml +10 -7
  122. data/locales/ru.yml +28 -0
  123. data/locales/sk.yml +26 -0
  124. data/locales/sr.yml +28 -0
  125. data/locales/sv-SE.yml +24 -0
  126. data/locales/sv.yml +24 -0
  127. data/locales/sw.yml +28 -0
  128. data/locales/ta.yml +24 -0
  129. data/locales/tr.yml +24 -0
  130. data/locales/uk.yml +28 -0
  131. data/locales/vi.yml +20 -0
  132. data/locales/zh-CN.yml +20 -0
  133. data/locales/zh-HK.yml +20 -0
  134. data/locales/zh-TW.yml +20 -0
  135. data/stylesheets/pagy-tailwind.css +68 -0
  136. data/stylesheets/pagy.css +83 -0
  137. metadata +185 -94
  138. data/lib/config/pagy.rb +0 -258
  139. data/lib/javascripts/pagy-dev.js +0 -112
  140. data/lib/javascripts/pagy-module.js +0 -111
  141. data/lib/javascripts/pagy.js +0 -1
  142. data/lib/locales/ar.yml +0 -30
  143. data/lib/locales/be.yml +0 -25
  144. data/lib/locales/bg.yml +0 -21
  145. data/lib/locales/bs.yml +0 -25
  146. data/lib/locales/ca.yml +0 -23
  147. data/lib/locales/ckb.yml +0 -18
  148. data/lib/locales/cs.yml +0 -23
  149. data/lib/locales/da.yml +0 -23
  150. data/lib/locales/de.yml +0 -21
  151. data/lib/locales/en.yml +0 -21
  152. data/lib/locales/fr.yml +0 -21
  153. data/lib/locales/hr.yml +0 -25
  154. data/lib/locales/id.yml +0 -19
  155. data/lib/locales/it.yml +0 -21
  156. data/lib/locales/ja.yml +0 -19
  157. data/lib/locales/km.yml +0 -19
  158. data/lib/locales/ko.yml +0 -19
  159. data/lib/locales/nb.yml +0 -21
  160. data/lib/locales/nl.yml +0 -21
  161. data/lib/locales/nn.yml +0 -21
  162. data/lib/locales/pl.yml +0 -25
  163. data/lib/locales/ru.yml +0 -27
  164. data/lib/locales/sr.yml +0 -25
  165. data/lib/locales/sv-SE.yml +0 -21
  166. data/lib/locales/sv.yml +0 -21
  167. data/lib/locales/sw.yml +0 -23
  168. data/lib/locales/ta.yml +0 -23
  169. data/lib/locales/tr.yml +0 -19
  170. data/lib/locales/uk.yml +0 -25
  171. data/lib/locales/vi.yml +0 -17
  172. data/lib/locales/zh-CN.yml +0 -19
  173. data/lib/locales/zh-HK.yml +0 -19
  174. data/lib/locales/zh-TW.yml +0 -19
  175. data/lib/pagy/backend.rb +0 -39
  176. data/lib/pagy/calendar/helper.rb +0 -65
  177. data/lib/pagy/calendar.rb +0 -126
  178. data/lib/pagy/countless.rb +0 -37
  179. data/lib/pagy/exceptions.rb +0 -25
  180. data/lib/pagy/extras/arel.rb +0 -36
  181. data/lib/pagy/extras/array.rb +0 -24
  182. data/lib/pagy/extras/bootstrap.rb +0 -108
  183. data/lib/pagy/extras/bulma.rb +0 -105
  184. data/lib/pagy/extras/calendar.rb +0 -53
  185. data/lib/pagy/extras/countless.rb +0 -37
  186. data/lib/pagy/extras/elasticsearch_rails.rb +0 -80
  187. data/lib/pagy/extras/foundation.rb +0 -105
  188. data/lib/pagy/extras/frontend_helpers.rb +0 -67
  189. data/lib/pagy/extras/gearbox.rb +0 -54
  190. data/lib/pagy/extras/headers.rb +0 -53
  191. data/lib/pagy/extras/i18n.rb +0 -26
  192. data/lib/pagy/extras/items.rb +0 -61
  193. data/lib/pagy/extras/jsonapi.rb +0 -79
  194. data/lib/pagy/extras/materialize.rb +0 -96
  195. data/lib/pagy/extras/meilisearch.rb +0 -65
  196. data/lib/pagy/extras/metadata.rb +0 -38
  197. data/lib/pagy/extras/navs.rb +0 -51
  198. data/lib/pagy/extras/overflow.rb +0 -80
  199. data/lib/pagy/extras/searchkick.rb +0 -67
  200. data/lib/pagy/extras/semantic.rb +0 -95
  201. data/lib/pagy/extras/standalone.rb +0 -60
  202. data/lib/pagy/extras/support.rb +0 -40
  203. data/lib/pagy/extras/trim.rb +0 -29
  204. data/lib/pagy/extras/uikit.rb +0 -97
  205. data/lib/pagy/frontend.rb +0 -114
  206. data/lib/pagy/i18n.rb +0 -165
  207. data/lib/pagy/url_helpers.rb +0 -27
  208. data/lib/stylesheets/pagy.css +0 -61
  209. data/lib/stylesheets/pagy.scss +0 -50
  210. data/lib/stylesheets/pagy.tailwind.scss +0 -24
  211. /data/{lib/javascripts/pagy-module.d.ts → javascripts/pagy.d.ts} +0 -0
@@ -1,65 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/meilisearch
2
- # frozen_string_literal: true
3
-
4
- class Pagy # :nodoc:
5
- DEFAULT[:meilisearch_search] ||= :ms_search
6
- DEFAULT[:meilisearch_pagy_search] ||= :pagy_search
7
-
8
- # Paginate Meilisearch results
9
- module MeilisearchExtra
10
- module ModelExtension # :nodoc:
11
- # Return an array used to delay the call of #search
12
- # after the pagination variables are merged to the options
13
- def pagy_meilisearch(query, params = {})
14
- [self, query, params]
15
- end
16
- alias_method DEFAULT[:meilisearch_pagy_search], :pagy_meilisearch
17
- end
18
- Pagy::Meilisearch = ModelExtension
19
-
20
- # Extension for the Pagy class
21
- module PagyExtension
22
- # Create a Pagy object from a Meilisearch results
23
- def new_from_meilisearch(results, vars = {})
24
- vars[:items] = results.raw_answer['hitsPerPage']
25
- vars[:page] = results.raw_answer['page']
26
- vars[:count] = results.raw_answer['totalHits']
27
-
28
- new(vars)
29
- end
30
- end
31
- Pagy.extend PagyExtension
32
-
33
- # Add specialized backend methods to paginate Meilisearch results
34
- module BackendAddOn
35
- private
36
-
37
- # Return Pagy object and results
38
- def pagy_meilisearch(pagy_search_args, vars = {})
39
- model, term, options = pagy_search_args
40
- vars = pagy_meilisearch_get_vars(nil, vars)
41
- options[:hits_per_page] = vars[:items]
42
- options[:page] = vars[:page]
43
- results = model.send(:ms_search, term, options)
44
- vars[:count] = results.raw_answer['totalHits']
45
-
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_meilisearch(pagy_search_args, vars.merge(page: pagy.page)) \
49
- if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
50
-
51
- [pagy, results]
52
- 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
- end
63
- Backend.prepend BackendAddOn
64
- end
65
- end
@@ -1,38 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/metadata
2
- # frozen_string_literal: true
3
-
4
- require 'pagy/url_helpers'
5
-
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 ]
9
-
10
- # Add a specialized backend method for pagination metadata
11
- module MetadataExtra
12
- private
13
-
14
- include UrlHelpers
15
-
16
- # Return the metadata hash
17
- def pagy_metadata(pagy, absolute: nil)
18
- scaffold_url = pagy_url_for(pagy, PAGE_TOKEN, absolute:)
19
- {}.tap do |metadata|
20
- keys = defined?(Calendar) && pagy.is_a?(Calendar) ? pagy.vars[:metadata] - %i[count items] : pagy.vars[:metadata]
21
- keys.each do |key|
22
- metadata[key] = case key
23
- when :scaffold_url then scaffold_url
24
- when :first_url then scaffold_url.sub(PAGE_TOKEN, 1.to_s)
25
- when :prev_url then scaffold_url.sub(PAGE_TOKEN, pagy.prev.to_s)
26
- when :page_url then scaffold_url.sub(PAGE_TOKEN, pagy.page.to_s)
27
- when :next_url then scaffold_url.sub(PAGE_TOKEN, pagy.next.to_s)
28
- when :last_url then scaffold_url.sub(PAGE_TOKEN, pagy.last.to_s)
29
- else pagy.send(key)
30
- end
31
- rescue NoMethodError
32
- raise VariableError.new(pagy, :metadata, 'to contain known keys', key)
33
- end
34
- end
35
- end
36
- end
37
- Backend.prepend MetadataExtra
38
- end
@@ -1,51 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/navs
2
- # frozen_string_literal: true
3
-
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: '',
12
- nav_aria_label: nil, nav_i18n_key: nil, **vars)
13
- sequels = pagy.sequels(**vars)
14
- p_id = %( id="#{pagy_id}") if pagy_id
15
- link = pagy_link_proc(pagy, link_extra:)
16
- tags = { 'before' => prev_html(pagy, link),
17
- 'link' => %(<span class="page">#{link.call(PAGE_TOKEN, LABEL_TOKEN)}</span>),
18
- 'active' => %(<span class="page active">) +
19
- %(<a role="link" aria-current="page" aria-disabled="true">#{LABEL_TOKEN}</a></span>),
20
- 'gap' => %(<span class="page gap">#{pagy_t 'pagy.gap'}</span>),
21
- 'after' => next_html(pagy, link) }
22
-
23
- %(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy pagy-nav-js pagination" #{
24
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
25
- pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))
26
- }></nav>)
27
- end
28
-
29
- # Javascript combo pagination: it returns a nav and a JSON tag used by the pagy.js file
30
- def pagy_combo_nav_js(pagy, pagy_id: nil, link_extra: '',
31
- nav_aria_label: nil, nav_i18n_key: nil)
32
- p_id = %( id="#{pagy_id}") if pagy_id
33
- link = pagy_link_proc(pagy, link_extra:)
34
- p_page = pagy.page
35
- p_pages = pagy.pages
36
- input = %(<input name="page" type="number" min="1" max="#{p_pages}" value="#{p_page}" ) +
37
- %(style="padding: 0; text-align: center; width: #{p_pages.to_s.length + 1}rem;" aria-current="page">)
38
-
39
- %(<nav#{p_id} class="pagy pagy-combo-nav-js pagination" #{
40
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
41
- pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))}>#{
42
- prev_html(pagy, link)
43
- }<span class="pagy-combo-input">#{
44
- pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)
45
- }</span>#{
46
- next_html(pagy, link)
47
- }</nav>)
48
- end
49
- end
50
- Frontend.prepend NavsExtra
51
- end
@@ -1,80 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/overflow
2
- # frozen_string_literal: true
3
-
4
- class Pagy # :nodoc:
5
- DEFAULT[:overflow] = :empty_page
6
-
7
- # Handles OverflowError exceptions for different classes with different options
8
- module OverflowExtra
9
- # Support for Pagy class
10
- module PagyOverride
11
- # Is the requested page overflowing?
12
- def overflow?
13
- @overflow
14
- end
15
-
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])
39
- end
40
- end
41
-
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
49
- end
50
- end
51
- end
52
- end
53
- Pagy.prepend PagyOverride
54
- Pagy::Calendar.prepend PagyOverride if defined?(Calendar)
55
-
56
- # Support for Pagy::Countless class
57
- module CountlessOverride
58
- # Add rescue clause for different behaviors
59
- def finalize(items)
60
- @overflow = false
61
- super
62
- rescue OverflowError
63
- @overflow = true # add the overflow flag
64
- case @vars[:overflow]
65
- when :exception
66
- raise # same as without the extra
67
- when :empty_page
68
- @offset = @items = @from = @to = 0 # vars relative to the actual page
69
- @vars[:size] = [] # no page in the series
70
- self
71
- else
72
- raise VariableError.new(self, :overflow, 'to be in [:empty_page, :exception]', @vars[:overflow])
73
- end
74
- end
75
- end
76
- # :nocov:
77
- Pagy::Countless.prepend CountlessOverride if defined?(Countless)
78
- # :nocov:
79
- end
80
- end
@@ -1,67 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/searchkick
2
- # frozen_string_literal: true
3
-
4
- class Pagy # :nodoc:
5
- DEFAULT[:searchkick_search] ||= :search
6
- DEFAULT[:searchkick_pagy_search] ||= :pagy_search
7
-
8
- # Paginate Searchkick::Results objects
9
- module SearchkickExtra
10
- module ModelExtension # :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
21
- Pagy::Searchkick = ModelExtension
22
-
23
- # Additions for the Pagy class
24
- module PagyExtension
25
- # Create a Pagy object from a Searchkick::Results object
26
- def new_from_searchkick(results, vars = {})
27
- vars[:items] = results.options[:per_page]
28
- vars[:page] = results.options[:page]
29
- vars[:count] = results.total_count
30
- new(vars)
31
- end
32
- end
33
- Pagy.extend PagyExtension
34
-
35
- # Add specialized backend methods to paginate Searchkick::Results
36
- module BackendAddOn
37
- private
38
-
39
- # Return Pagy object and results
40
- def pagy_searchkick(pagy_search_args, vars = {})
41
- model, term, options, block, *called = pagy_search_args
42
- vars = pagy_searchkick_get_vars(nil, vars)
43
- options[:per_page] = vars[:items]
44
- options[:page] = vars[:page]
45
- results = model.send(DEFAULT[:searchkick_search], term, **options, &block)
46
- vars[:count] = results.total_count
47
-
48
- pagy = ::Pagy.new(vars)
49
- # 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
- if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
52
-
53
- [pagy, called.empty? ? results : results.send(*called)]
54
- 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
- end
65
- Backend.prepend BackendAddOn
66
- end
67
- end
@@ -1,95 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/semantic
2
- # frozen_string_literal: true
3
-
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 SemanticExtra
10
- # Pagination for semantic: it returns the html with the series of links to the pages
11
- def pagy_semantic_nav(pagy, pagy_id: nil, link_extra: '',
12
- nav_aria_label: nil, nav_i18n_key: nil, **vars)
13
- p_id = %( id="#{pagy_id}") if pagy_id
14
- link = pagy_link_proc(pagy, link_extra:)
15
-
16
- html = +%(<div#{p_id} role="navigation" class="pagy-semantic-nav ui pagination menu" #{
17
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}>)
18
- html << semantic_prev_html(pagy, link)
19
- pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
20
- html << case item
21
- when Integer
22
- link.call(item, pagy.label_for(item), %(class="item"))
23
- when String
24
- %(<a role="link" class="item active" aria-current="page" aria-disabled="true">#{pagy.label_for(item)}</a>)
25
- when :gap
26
- %(<div class="disabled item">#{pagy_t 'pagy.gap'}</div>)
27
- else
28
- raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
29
- end
30
- end
31
- html << semantic_next_html(pagy, link)
32
- html << %(</div>)
33
- end
34
-
35
- # Javascript pagination for semantic: it returns a nav and a JSON tag used by the pagy.js file
36
- def pagy_semantic_nav_js(pagy, pagy_id: nil, link_extra: '',
37
- nav_aria_label: nil, nav_i18n_key: nil, **vars)
38
- sequels = pagy.sequels(**vars)
39
- p_id = %( id="#{pagy_id}") if pagy_id
40
- link = pagy_link_proc(pagy, link_extra:)
41
- tags = { 'before' => semantic_prev_html(pagy, link),
42
- 'link' => link.call(PAGE_TOKEN, LABEL_TOKEN, %(class="item")),
43
- 'active' => %(<a role="link" class="item active" aria-current="page" aria-disabled="true">#{LABEL_TOKEN}</a>),
44
- 'gap' => %(<div class="disabled item">#{pagy_t('pagy.gap')}</div>),
45
- 'after' => semantic_next_html(pagy, link) }
46
-
47
- %(<div#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-semantic-nav-js ui pagination menu" role="navigation" #{
48
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
49
- pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></div>)
50
- end
51
-
52
- # Combo pagination for semantic: it returns a nav and a JSON tag used by the pagy.js file
53
- def pagy_semantic_combo_nav_js(pagy, pagy_id: nil, link_extra: '',
54
- nav_aria_label: nil, nav_i18n_key: nil)
55
- p_id = %( id="#{pagy_id}") if pagy_id
56
- link = pagy_link_proc(pagy, link_extra: %(class="item" #{link_extra}))
57
- p_page = pagy.page
58
- p_pages = pagy.pages
59
- input = %(<input name="page" type="number" min="1" max="#{p_pages}" value="#{
60
- p_page}" style="padding: 0; text-align: center; width: #{
61
- p_pages.to_s.length + 1}rem; margin: 0 0.3rem" aria-current="page">)
62
-
63
- %(<div#{p_id} class="pagy-semantic-combo-nav-js ui compact menu" role="navigation" #{
64
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
65
- pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))}>#{
66
- semantic_prev_html pagy, link
67
- }<div class="pagy-combo-input item">#{
68
- pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
69
- }</div> #{
70
- semantic_next_html pagy, link
71
- }</div>)
72
- end
73
-
74
- private
75
-
76
- def semantic_prev_html(pagy, link)
77
- if (p_prev = pagy.prev)
78
- link.call(p_prev, pagy_t('pagy.prev'), %(#{prev_aria_label_attr} class="item"))
79
- else
80
- +%(<div class="item disabled" role="link" aria-disabled="true" #{
81
- prev_aria_label_attr}>#{pagy_t('pagy.prev')}</div>)
82
- end
83
- end
84
-
85
- def semantic_next_html(pagy, link)
86
- if (p_next = pagy.next)
87
- link.call(p_next, pagy_t('pagy.next'), %(#{next_aria_label_attr} class="item"))
88
- else
89
- +%(<div class="item disabled" role="link" aria-disabled="true" #{
90
- next_aria_label_attr}>#{pagy_t('pagy.next')}</div>)
91
- end
92
- end
93
- end
94
- Frontend.prepend SemanticExtra
95
- end
@@ -1,60 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/standalone
2
- # frozen_string_literal: true
3
-
4
- require 'uri'
5
-
6
- class Pagy # :nodoc:
7
- # Use pagy without any request object, nor Rack environment/gem, nor any defined params method,
8
- # even in the irb/rails console without any app or config.
9
- module StandaloneExtra
10
- # Extracted from Rack::Utils and reformatted for rubocop
11
- # :nocov:
12
- module QueryUtils
13
- module_function
14
-
15
- def escape(str)
16
- URI.encode_www_form_component(str)
17
- end
18
-
19
- def build_nested_query(value, prefix = nil)
20
- case value
21
- when Array
22
- value.map { |v| build_nested_query(v, "#{prefix}[]") }.join('&')
23
- when Hash
24
- value.map do |k, v|
25
- build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
26
- end.delete_if(&:empty?).join('&')
27
- when nil
28
- escape(prefix)
29
- else
30
- raise ArgumentError, 'value must be a Hash' if prefix.nil?
31
-
32
- "#{escape(prefix)}=#{escape(value)}"
33
- end
34
- end
35
- end
36
- # :nocov:
37
-
38
- # Return the URL for the page. If there is no pagy.vars[:url]
39
- # it works exactly as the regular #pagy_url_for, relying on the params method and Rack.
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, **_)
42
- return super unless pagy.vars[:url]
43
-
44
- vars = pagy.vars
45
- params = pagy.params.is_a?(Hash) ? pagy.params.clone : {} # safe when it gets reused
46
- pagy_set_query_params(page, vars, params)
47
- params = pagy.params.call(params) if pagy.params.is_a?(Proc)
48
- query_string = "?#{QueryUtils.build_nested_query(params)}"
49
- "#{vars[:url]}#{query_string}#{vars[:fragment]}"
50
- end
51
- end
52
- UrlHelpers.prepend StandaloneExtra
53
-
54
- # Define a dummy params method if it's not already defined in the including module
55
- module Backend
56
- def self.included(controller)
57
- controller.define_method(:params) { {} } unless controller.method_defined?(:params)
58
- end
59
- end
60
- end
@@ -1,40 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/support
2
- # frozen_string_literal: true
3
-
4
- class Pagy # :nodoc:
5
- # Extra support for features like: incremental, auto-incremental and infinite pagination
6
- module SupportExtra
7
- # Return the previous page URL string or nil
8
- def pagy_prev_url(pagy, absolute: false)
9
- pagy_url_for(pagy, pagy.prev, absolute:) if pagy.prev
10
- end
11
-
12
- # Return the next page URL string or nil
13
- def pagy_next_url(pagy, absolute: false)
14
- pagy_url_for(pagy, pagy.next, absolute:) if pagy.next
15
- end
16
-
17
- # Return the HTML string for the enabled/disabled previous page link
18
- def pagy_prev_html(pagy, text: pagy_t('pagy.prev'), link_extra: '')
19
- link = pagy_link_proc(pagy, link_extra:)
20
- prev_html(pagy, link, text:)
21
- end
22
-
23
- # Return the HTML string for the enabled/disabled next page link
24
- def pagy_next_html(pagy, text: pagy_t('pagy.next'), link_extra: '')
25
- link = pagy_link_proc(pagy, link_extra:)
26
- next_html(pagy, link, text:)
27
- end
28
-
29
- # Conditionally return the HTML link tag string for the previous page
30
- def pagy_prev_link_tag(pagy, absolute: false)
31
- %(<link href="#{pagy_url_for(pagy, pagy.prev, absolute:)}" rel="prev"/>) if pagy.prev
32
- end
33
-
34
- # Conditionally return the HTML link tag string for the next page
35
- def pagy_next_link_tag(pagy, absolute: false)
36
- %(<link href="#{pagy_url_for(pagy, pagy.next, absolute:)}" rel="next"/>) if pagy.next
37
- end
38
- end
39
- Frontend.prepend SupportExtra
40
- end
@@ -1,29 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/trim
2
- # frozen_string_literal: true
3
-
4
- class Pagy # :nodoc:
5
- DEFAULT[:trim_extra] = true # extra enabled by default
6
-
7
- # Remove the page=1 param from the first page link
8
- module TrimExtra
9
- # Override the original pagy_link_proc.
10
- # Call the pagy_trim method if the trim_extra is enabled.
11
- def pagy_link_proc(pagy, link_extra: '')
12
- link_proc = super(pagy, link_extra:)
13
- return link_proc unless pagy.vars[:trim_extra]
14
-
15
- lambda do |page, text = pagy.label_for(page), extra = ''|
16
- link = +link_proc.call(page, text, extra)
17
- return link unless page.to_s == '1'
18
-
19
- pagy_trim(pagy, link)
20
- end
21
- end
22
-
23
- # Remove the the :page_param param from the first page link
24
- def pagy_trim(pagy, link)
25
- link.sub!(/[?&]#{pagy.vars[:page_param]}=1\b(?!&)|\b#{pagy.vars[:page_param]}=1&/, '')
26
- end
27
- end
28
- Frontend.prepend TrimExtra
29
- end
@@ -1,97 +0,0 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/uikit
2
- # frozen_string_literal: true
3
-
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 UikitExtra
10
- # Pagination for uikit: it returns the html with the series of links to the pages
11
- def pagy_uikit_nav(pagy, pagy_id: nil, link_extra: '',
12
- nav_aria_label: nil, nav_i18n_key: nil, **vars)
13
- p_id = %( id="#{pagy_id}") if pagy_id
14
- link = pagy_link_proc(pagy, link_extra:)
15
-
16
- html = +%(<ul#{p_id} class="pagy-uikit-nav uk-pagination uk-flex-center" role="navigation" #{
17
-
18
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}>#{uikit_prev_html(pagy, link)})
19
- pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
20
- html << case item
21
- when Integer
22
- %(<li>#{link.call(item)}</li>)
23
- when String
24
- %(<li class="uk-active"><span role="link" aria-current="page" aria-disabled="true">#{
25
- pagy.label_for(item)}</span></li>)
26
- when :gap
27
- %(<li class="uk-disabled"><span>#{pagy_t 'pagy.gap'}</span></li>)
28
- else
29
- raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
30
- end
31
- end
32
- html << uikit_next_html(pagy, link)
33
- html << %(</ul>)
34
- end
35
-
36
- # Javascript pagination for uikit: it returns a nav and a JSON tag used by the pagy.js file
37
- def pagy_uikit_nav_js(pagy, pagy_id: nil, link_extra: '',
38
- nav_aria_label: nil, nav_i18n_key: nil, **vars)
39
- sequels = pagy.sequels(**vars)
40
- p_id = %( id="#{pagy_id}") if pagy_id
41
- link = pagy_link_proc(pagy, link_extra:)
42
- tags = { 'before' => uikit_prev_html(pagy, link),
43
- 'link' => %(<li>#{link.call(PAGE_TOKEN, LABEL_TOKEN)}</li>),
44
- 'active' => %(<li class="uk-active"><span role="link" aria-current="page" aria-disabled="true">#{
45
- LABEL_TOKEN}</span></li>),
46
- 'gap' => %(<li class="uk-disabled"><span>#{pagy_t 'pagy.gap'}</span></li>),
47
- 'after' => uikit_next_html(pagy, link) }
48
-
49
- %(<ul#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-uikit-nav-js uk-pagination uk-flex-center" role="navigation" #{
50
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
51
- pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></ul>)
52
- end
53
-
54
- # Javascript combo pagination for uikit: it returns a nav and a JSON tag used by the pagy.js file
55
- def pagy_uikit_combo_nav_js(pagy, pagy_id: nil, link_extra: '',
56
- nav_aria_label: nil, nav_i18n_key: nil)
57
- p_id = %( id="#{pagy_id}") if pagy_id
58
- link = pagy_link_proc(pagy, link_extra:)
59
- p_page = pagy.page
60
- p_pages = pagy.pages
61
- input = %(<input name="page" type="number" min="1" max="#{p_pages}" value="#{
62
- p_page}" style="text-align: center; width: #{p_pages.to_s.length + 1}rem;" aria-current="page">)
63
-
64
- %(<ul#{p_id} class="pagy-uikit-combo-nav-js uk-button-group uk-pagination uk-flex-center" role="navigation" #{
65
- nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
66
- pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
67
- }>#{
68
- uikit_prev_html pagy, link
69
- }<li>#{
70
- pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
71
- }</li>#{
72
- uikit_next_html pagy, link
73
- }</ul>)
74
- end
75
-
76
- private
77
-
78
- def uikit_prev_html(pagy, link)
79
- previous_span = %(<span uk-pagination-previous></span>)
80
- if (p_prev = pagy.prev)
81
- %(<li>#{link.call(p_prev, previous_span, prev_aria_label_attr)}</li>)
82
- else
83
- %(<li class="uk-disabled"><span role="link" aria-disabled="true" #{prev_aria_label_attr}>#{previous_span}</a></li>)
84
- end
85
- end
86
-
87
- def uikit_next_html(pagy, link)
88
- next_span = %(<span uk-pagination-next></span>)
89
- if (p_next = pagy.next)
90
- %(<li>#{link.call(p_next, next_span, next_aria_label_attr)}</li>)
91
- else
92
- %(<li class="uk-disabled"><span role="link" aria-disabled="true" #{prev_aria_label_attr}>#{next_span}</span></li>)
93
- end
94
- end
95
- end
96
- Frontend.include UikitExtra
97
- end