pagy 5.7.5 → 8.6.2
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.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/apps/calendar.ru +745 -0
- data/apps/demo.ru +435 -0
- data/apps/rails.ru +213 -0
- data/apps/repro.ru +177 -0
- data/apps/tmp/calendar.sqlite3 +0 -0
- data/apps/tmp/calendar.sqlite3-shm +0 -0
- data/apps/tmp/calendar.sqlite3-wal +0 -0
- data/apps/tmp/local_secret.txt +1 -0
- data/bin/pagy +100 -0
- data/{lib/config → config}/pagy.rb +72 -96
- data/javascripts/pagy-module.js +100 -0
- data/javascripts/pagy.d.ts +5 -0
- data/javascripts/pagy.js +4 -0
- data/javascripts/pagy.min.js +4 -0
- data/javascripts/pagy.min.js.map +10 -0
- data/javascripts/pagy.mjs +100 -0
- data/lib/optimist.rb +1022 -0
- data/lib/pagy/backend.rb +16 -4
- data/lib/pagy/calendar/day.rb +22 -10
- data/lib/pagy/calendar/month.rb +35 -9
- data/lib/pagy/calendar/quarter.rb +36 -10
- data/lib/pagy/calendar/unit.rb +106 -0
- data/lib/pagy/calendar/week.rb +16 -16
- data/lib/pagy/calendar/year.rb +15 -9
- data/lib/pagy/calendar.rb +60 -68
- data/lib/pagy/console.rb +3 -3
- data/lib/pagy/countless.rb +17 -12
- data/lib/pagy/exceptions.rb +1 -1
- data/lib/pagy/extras/arel.rb +2 -2
- data/lib/pagy/extras/array.rb +2 -2
- data/lib/pagy/extras/bootstrap.rb +57 -53
- data/lib/pagy/extras/bulma.rb +53 -57
- data/lib/pagy/extras/calendar.rb +54 -37
- data/lib/pagy/extras/countless.rb +3 -3
- data/lib/pagy/extras/elasticsearch_rails.rb +12 -11
- data/lib/pagy/extras/foundation.rb +59 -54
- data/lib/pagy/extras/gearbox.rb +32 -19
- data/lib/pagy/extras/headers.rb +11 -11
- data/lib/pagy/extras/i18n.rb +5 -5
- data/lib/pagy/extras/items.rb +34 -24
- data/lib/pagy/extras/{frontend_helpers.rb → js_tools.rb} +24 -24
- data/lib/pagy/extras/jsonapi.rb +79 -0
- data/lib/pagy/extras/materialize.rb +63 -47
- data/lib/pagy/extras/meilisearch.rb +26 -22
- data/lib/pagy/extras/metadata.rb +13 -9
- data/lib/pagy/extras/overflow.rb +13 -10
- data/lib/pagy/extras/pagy.rb +82 -0
- data/lib/pagy/extras/searchkick.rb +12 -11
- data/lib/pagy/extras/semantic.rb +57 -45
- data/lib/pagy/extras/size.rb +40 -0
- data/lib/pagy/extras/standalone.rb +12 -16
- data/lib/pagy/extras/trim.rb +13 -13
- data/lib/pagy/extras/uikit.rb +60 -46
- data/lib/pagy/frontend.rb +62 -45
- data/lib/pagy/i18n.rb +4 -3
- data/lib/pagy/url_helpers.rb +13 -25
- data/lib/pagy.rb +61 -59
- data/locales/ar.yml +28 -0
- data/locales/be.yml +25 -0
- data/locales/bg.yml +21 -0
- data/locales/bs.yml +25 -0
- data/locales/ca.yml +21 -0
- data/locales/ckb.yml +18 -0
- data/locales/cs.yml +23 -0
- data/locales/da.yml +21 -0
- data/locales/de.yml +21 -0
- data/locales/en.yml +21 -0
- data/locales/es.yml +21 -0
- data/locales/fr.yml +21 -0
- data/locales/hr.yml +25 -0
- data/locales/id.yml +19 -0
- data/locales/it.yml +21 -0
- data/locales/ja.yml +19 -0
- data/locales/km.yml +19 -0
- data/locales/ko.yml +17 -0
- data/locales/nb.yml +21 -0
- data/locales/nl.yml +21 -0
- data/locales/nn.yml +21 -0
- data/locales/pl.yml +25 -0
- data/locales/pt-BR.yml +21 -0
- data/locales/pt.yml +21 -0
- data/locales/ru.yml +25 -0
- data/locales/sr.yml +25 -0
- data/locales/sv-SE.yml +21 -0
- data/locales/sv.yml +21 -0
- data/locales/sw.yml +23 -0
- data/locales/ta.yml +23 -0
- data/locales/tr.yml +19 -0
- data/locales/uk.yml +25 -0
- data/locales/vi.yml +17 -0
- data/locales/zh-CN.yml +19 -0
- data/locales/zh-HK.yml +19 -0
- data/locales/zh-TW.yml +19 -0
- data/stylesheets/pagy.css +46 -0
- data/stylesheets/pagy.scss +48 -0
- data/stylesheets/pagy.tailwind.css +21 -0
- metadata +79 -66
- data/lib/javascripts/pagy-dev.js +0 -118
- data/lib/javascripts/pagy-module.d.ts +0 -30
- data/lib/javascripts/pagy-module.js +0 -117
- data/lib/javascripts/pagy.js +0 -1
- data/lib/locales/ar.yml +0 -26
- data/lib/locales/bg.yml +0 -22
- data/lib/locales/bs.yml +0 -24
- data/lib/locales/ca.yml +0 -22
- data/lib/locales/cs.yml +0 -22
- data/lib/locales/da.yml +0 -22
- data/lib/locales/de.yml +0 -22
- data/lib/locales/en.yml +0 -22
- data/lib/locales/es.yml +0 -22
- data/lib/locales/fr.yml +0 -22
- data/lib/locales/hr.yml +0 -24
- data/lib/locales/id.yml +0 -20
- data/lib/locales/it.yml +0 -22
- data/lib/locales/ja.yml +0 -20
- data/lib/locales/km.yml +0 -19
- data/lib/locales/ko.yml +0 -20
- data/lib/locales/nb.yml +0 -22
- data/lib/locales/nl.yml +0 -22
- data/lib/locales/pl.yml +0 -24
- data/lib/locales/pt-BR.yml +0 -22
- data/lib/locales/pt.yml +0 -22
- data/lib/locales/ru.yml +0 -24
- data/lib/locales/sr.yml +0 -23
- data/lib/locales/sv-SE.yml +0 -23
- data/lib/locales/sv.yml +0 -23
- data/lib/locales/sw.yml +0 -22
- data/lib/locales/ta.yml +0 -22
- data/lib/locales/tr.yml +0 -20
- data/lib/locales/uk.yml +0 -24
- data/lib/locales/zh-CN.yml +0 -20
- data/lib/locales/zh-HK.yml +0 -20
- data/lib/locales/zh-TW.yml +0 -20
- data/lib/pagy/calendar/month_mixin.rb +0 -49
- data/lib/pagy/extras/navs.rb +0 -63
- data/lib/pagy/extras/support.rb +0 -54
- data/lib/templates/bootstrap_nav.html.erb +0 -24
- data/lib/templates/bootstrap_nav.html.haml +0 -34
- data/lib/templates/bootstrap_nav.html.slim +0 -34
- data/lib/templates/bulma_nav.html.erb +0 -24
- data/lib/templates/bulma_nav.html.haml +0 -32
- data/lib/templates/bulma_nav.html.slim +0 -32
- data/lib/templates/foundation_nav.html.erb +0 -24
- data/lib/templates/foundation_nav.html.haml +0 -34
- data/lib/templates/foundation_nav.html.slim +0 -34
- data/lib/templates/nav.html.erb +0 -22
- data/lib/templates/nav.html.haml +0 -30
- data/lib/templates/nav.html.slim +0 -29
- data/lib/templates/uikit_nav.html.erb +0 -15
- data/lib/templates/uikit_nav.html.haml +0 -28
- data/lib/templates/uikit_nav.html.slim +0 -28
@@ -0,0 +1,40 @@
|
|
1
|
+
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/size
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
class Pagy # :nodoc:
|
5
|
+
# Implement the legacy bar using the array size.
|
6
|
+
# Unless you have very specific requirements, use the faster and better looking default bar.
|
7
|
+
module SizeExtra
|
8
|
+
# Setup @items based on the :gearbox_items variable
|
9
|
+
def series(size: @vars[:size], **_)
|
10
|
+
return super unless size.is_a?(Array)
|
11
|
+
return [] if size == []
|
12
|
+
raise VariableError.new(self, :size, 'to be an Array of 4 Integers or []', size) \
|
13
|
+
unless size.is_a?(Array) && size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
|
14
|
+
|
15
|
+
[].tap do |series|
|
16
|
+
# This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
|
17
|
+
# However the behavior of the legacy nav bar was taken straight from WillPaginate and Kaminari:
|
18
|
+
# it's ill-concieved and complicates the experience of devs and users.
|
19
|
+
left_gap_start = 1 + size[0]
|
20
|
+
left_gap_end = @page - size[1] - 1
|
21
|
+
right_gap_start = @page + size[2] + 1
|
22
|
+
right_gap_end = @last - size[3]
|
23
|
+
left_gap_end = right_gap_end if left_gap_end > right_gap_end
|
24
|
+
right_gap_start = left_gap_start if left_gap_start > right_gap_start
|
25
|
+
start = 1
|
26
|
+
if (left_gap_end - left_gap_start).positive?
|
27
|
+
series.push(*start...left_gap_start, :gap)
|
28
|
+
start = left_gap_end + 1
|
29
|
+
end
|
30
|
+
if (right_gap_end - right_gap_start).positive?
|
31
|
+
series.push(*start...right_gap_start, :gap)
|
32
|
+
start = right_gap_end + 1
|
33
|
+
end
|
34
|
+
series.push(*start..@last)
|
35
|
+
series[series.index(@page)] = @page.to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
prepend SizeExtra
|
40
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/standalone
|
1
|
+
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/standalone
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'uri'
|
@@ -8,6 +8,7 @@ class Pagy # :nodoc:
|
|
8
8
|
# even in the irb/rails console without any app or config.
|
9
9
|
module StandaloneExtra
|
10
10
|
# Extracted from Rack::Utils and reformatted for rubocop
|
11
|
+
# :nocov:
|
11
12
|
module QueryUtils
|
12
13
|
module_function
|
13
14
|
|
@@ -24,36 +25,31 @@ class Pagy # :nodoc:
|
|
24
25
|
build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
|
25
26
|
end.delete_if(&:empty?).join('&')
|
26
27
|
when nil
|
27
|
-
prefix
|
28
|
+
escape(prefix)
|
28
29
|
else
|
29
30
|
raise ArgumentError, 'value must be a Hash' if prefix.nil?
|
30
31
|
|
31
|
-
"#{prefix}=#{escape(value)}"
|
32
|
+
"#{escape(prefix)}=#{escape(value)}"
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
36
|
+
# :nocov:
|
35
37
|
|
36
38
|
# Return the URL for the page. If there is no pagy.vars[:url]
|
37
39
|
# it works exactly as the regular #pagy_url_for, relying on the params method and Rack.
|
38
40
|
# If there is a defined pagy.vars[:url] variable it does not need the params method nor Rack.
|
39
|
-
def pagy_url_for(pagy, page, absolute:
|
41
|
+
def pagy_url_for(pagy, page, absolute: false, **_)
|
40
42
|
return super unless pagy.vars[:url]
|
41
43
|
|
42
|
-
vars
|
43
|
-
|
44
|
-
|
45
|
-
params
|
46
|
-
|
47
|
-
params[items_param] = vars[:items] if vars[:items_extra]
|
48
|
-
query_string = "?#{QueryUtils.build_nested_query(pagy_deprecated_params(pagy, params))}" # remove in 6.0
|
49
|
-
# params = pagy.params.call(params) if pagy.params.is_a?(Proc) # add in 6.0
|
50
|
-
# query_string = "?#{Rack::Utils.build_nested_query(params)}" # add in 6.0
|
44
|
+
vars = pagy.vars
|
45
|
+
params = vars[:params].is_a?(Hash) ? vars[:params].clone : {} # safe when it gets reused
|
46
|
+
pagy_set_query_params(page, vars, params)
|
47
|
+
params = vars[:params].(params) if vars[:params].is_a?(Proc)
|
48
|
+
query_string = "?#{QueryUtils.build_nested_query(params)}"
|
51
49
|
"#{vars[:url]}#{query_string}#{vars[:fragment]}"
|
52
50
|
end
|
53
51
|
end
|
54
|
-
|
55
|
-
Frontend.prepend StandaloneExtra
|
56
|
-
Backend.prepend StandaloneExtra
|
52
|
+
UrlHelpers.prepend StandaloneExtra
|
57
53
|
|
58
54
|
# Define a dummy params method if it's not already defined in the including module
|
59
55
|
module Backend
|
data/lib/pagy/extras/trim.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/trim
|
1
|
+
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/trim
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
class Pagy # :nodoc:
|
@@ -6,23 +6,23 @@ 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
|
10
|
-
# Call the pagy_trim method if the trim_extra is enabled
|
11
|
-
def
|
12
|
-
|
13
|
-
return
|
9
|
+
# Override the original pagy_a_proc.
|
10
|
+
# Call the pagy_trim method for page 1 if the trim_extra is enabled
|
11
|
+
def pagy_anchor(pagy)
|
12
|
+
a_proc = super
|
13
|
+
return a_proc unless pagy.vars[:trim_extra]
|
14
14
|
|
15
|
-
lambda do |page, text = pagy.label_for(page),
|
16
|
-
|
17
|
-
return
|
15
|
+
lambda do |page, text = pagy.label_for(page), **opts|
|
16
|
+
a = +a_proc.(page, text, **opts)
|
17
|
+
return a unless page.to_s == '1'
|
18
18
|
|
19
|
-
pagy_trim(pagy,
|
19
|
+
pagy_trim(pagy, a) # in method for isolated testing
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
# Remove the the :page_param param from the first page
|
24
|
-
def pagy_trim(pagy,
|
25
|
-
|
23
|
+
# Remove the the :page_param param from the first page anchor
|
24
|
+
def pagy_trim(pagy, a)
|
25
|
+
a.sub!(/[?&]#{pagy.vars[:page_param]}=1\b(?!&)|\b#{pagy.vars[:page_param]}=1&/, '')
|
26
26
|
end
|
27
27
|
end
|
28
28
|
Frontend.prepend TrimExtra
|
data/lib/pagy/extras/uikit.rb
CHANGED
@@ -1,82 +1,96 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/uikit
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
warn '[PAGY WARNING] The uikit extra has been discontinued and it will be removed in v9 ' \
|
4
|
+
'(https://github.com/ddnexus/pagy/discussions/672#discussioncomment-9212328)'
|
5
|
+
|
6
|
+
require_relative 'js_tools'
|
5
7
|
|
6
8
|
class Pagy # :nodoc:
|
7
9
|
# Frontend modules are specially optimized for performance.
|
8
10
|
# The resulting code may not look very elegant, but produces the best benchmarks
|
9
11
|
module UikitExtra
|
10
12
|
# Pagination for uikit: it returns the html with the series of links to the pages
|
11
|
-
def pagy_uikit_nav(pagy,
|
12
|
-
|
13
|
-
|
13
|
+
def pagy_uikit_nav(pagy, id: nil, aria_label: nil, **vars)
|
14
|
+
id = %( id="#{id}") if id
|
15
|
+
a = pagy_anchor(pagy)
|
14
16
|
|
15
|
-
html =
|
17
|
+
html = %(<ul#{id} class="pagy-uikit nav uk-pagination uk-flex-center" role="navigation" #{
|
18
|
+
nav_aria_label(pagy, aria_label:)}>#{
|
19
|
+
uikit_prev_html(pagy, a)})
|
16
20
|
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
17
21
|
html << case item
|
18
|
-
when Integer
|
19
|
-
|
20
|
-
when
|
21
|
-
|
22
|
+
when Integer
|
23
|
+
%(<li>#{a.(item)}</li>)
|
24
|
+
when String
|
25
|
+
%(<li class="uk-active"><span role="link" aria-current="page" aria-disabled="true">#{
|
26
|
+
pagy.label_for(item)}</span></li>)
|
27
|
+
when :gap
|
28
|
+
%(<li class="uk-disabled"><span>#{pagy_t 'pagy.gap'}</span></li>)
|
29
|
+
else
|
30
|
+
raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
22
31
|
end
|
23
32
|
end
|
24
|
-
html <<
|
25
|
-
html << %(</ul>)
|
33
|
+
html << %(#{uikit_next_html(pagy, a)}</ul>)
|
26
34
|
end
|
27
35
|
|
28
|
-
# Javascript pagination for uikit: it returns a nav
|
29
|
-
def pagy_uikit_nav_js(pagy,
|
36
|
+
# Javascript pagination for uikit: it returns a nav with a data-pagy attribute used by the pagy.js file
|
37
|
+
def pagy_uikit_nav_js(pagy, id: nil, aria_label: nil, **vars)
|
30
38
|
sequels = pagy.sequels(**vars)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
id = %( id="#{id}") if id
|
40
|
+
a = pagy_anchor(pagy)
|
41
|
+
tokens = { 'before' => uikit_prev_html(pagy, a),
|
42
|
+
'a' => %(<li>#{a.(PAGE_TOKEN, LABEL_TOKEN)}</li>),
|
43
|
+
'current' => %(<li class="uk-active"><span role="link" aria-current="page" aria-disabled="true">#{
|
44
|
+
LABEL_TOKEN}</span></li>),
|
45
|
+
'gap' => %(<li class="uk-disabled"><span>#{pagy_t 'pagy.gap'}</span></li>),
|
46
|
+
'after' => uikit_next_html(pagy, a) }
|
38
47
|
|
39
|
-
%(<ul#{
|
40
|
-
|
48
|
+
%(<ul#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-uikit nav-js uk-pagination uk-flex-center" role="navigation" #{
|
49
|
+
nav_aria_label(pagy, aria_label:)} #{
|
50
|
+
pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
|
51
|
+
}></ul>)
|
41
52
|
end
|
42
53
|
|
43
|
-
# Javascript combo pagination for uikit: it returns a nav
|
44
|
-
def pagy_uikit_combo_nav_js(pagy,
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
# Javascript combo pagination for uikit: it returns a nav with a data-pagy attribute used by the pagy.js file
|
55
|
+
def pagy_uikit_combo_nav_js(pagy, id: nil, aria_label: nil)
|
56
|
+
id = %( id="#{id}") if id
|
57
|
+
a = pagy_anchor(pagy)
|
58
|
+
pages = pagy.pages
|
59
|
+
|
60
|
+
page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
|
61
|
+
%(style="text-align: center; width: #{pages.to_s.length + 1}rem;">#{JSTools::A_TAG})
|
51
62
|
|
52
|
-
%(<ul#{
|
53
|
-
|
63
|
+
%(<ul#{id} class="pagy-uikit combo-nav-js uk-button-group uk-pagination uk-flex-center" role="navigation" #{
|
64
|
+
nav_aria_label(pagy, aria_label:)} #{
|
65
|
+
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
|
54
66
|
}>#{
|
55
|
-
|
56
|
-
}<li>#{
|
57
|
-
pagy_t
|
58
|
-
}</li>#{
|
59
|
-
|
67
|
+
uikit_prev_html(pagy, a)
|
68
|
+
}<li><label>#{
|
69
|
+
pagy_t('pagy.combo_nav_js', page_input:, pages:)
|
70
|
+
}</label></li>#{
|
71
|
+
uikit_next_html(pagy, a)
|
60
72
|
}</ul>)
|
61
73
|
end
|
62
74
|
|
63
75
|
private
|
64
76
|
|
65
|
-
def
|
66
|
-
|
77
|
+
def uikit_prev_html(pagy, a)
|
78
|
+
span = %(<span uk-pagination-previous></span>)
|
67
79
|
if (p_prev = pagy.prev)
|
68
|
-
%(<li>#{
|
80
|
+
%(<li>#{a.(p_prev, span, aria_label: pagy_t('pagy.aria_label.prev'))}</li>)
|
69
81
|
else
|
70
|
-
%(<li class="uk-disabled"><a
|
82
|
+
%(<li class="uk-disabled"><a role="link" aria-disabled="true" aria-label="#{
|
83
|
+
pagy_t('pagy.aria_label.prev')}">#{span}</a></li>)
|
71
84
|
end
|
72
85
|
end
|
73
86
|
|
74
|
-
def
|
75
|
-
|
87
|
+
def uikit_next_html(pagy, a)
|
88
|
+
span = %(<span uk-pagination-next></span>)
|
76
89
|
if (p_next = pagy.next)
|
77
|
-
%(<li>#{
|
90
|
+
%(<li>#{a.(p_next, span, aria_label: pagy_t('pagy.aria_label.prev'))}</li>)
|
78
91
|
else
|
79
|
-
%(<li class="uk-disabled"><a
|
92
|
+
%(<li class="uk-disabled"><a role="link" aria-disabled="true" aria-label="#{
|
93
|
+
pagy_t('pagy.aria_label.next')}">#{span}</a></li>)
|
80
94
|
end
|
81
95
|
end
|
82
96
|
end
|
data/lib/pagy/frontend.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# See Pagy::Frontend API documentation: https://ddnexus.github.io/pagy/api/frontend
|
1
|
+
# See Pagy::Frontend API documentation: https://ddnexus.github.io/pagy/docs/api/frontend
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
require_relative 'url_helpers'
|
5
|
+
require_relative 'i18n'
|
6
6
|
|
7
7
|
class Pagy
|
8
8
|
# Used for search and replace, hardcoded also in the pagy.js file
|
9
|
-
|
10
|
-
|
9
|
+
PAGE_TOKEN = '__pagy_page__'
|
10
|
+
LABEL_TOKEN = '__pagy_label__'
|
11
11
|
|
12
12
|
# Frontend modules are specially optimized for performance.
|
13
13
|
# The resulting code may not look very elegant, but produces the best benchmarks
|
@@ -15,62 +15,56 @@ class Pagy
|
|
15
15
|
include UrlHelpers
|
16
16
|
|
17
17
|
# Generic pagination: it returns the html with the series of links to the pages
|
18
|
-
def pagy_nav(pagy,
|
19
|
-
|
20
|
-
|
21
|
-
p_prev = pagy.prev
|
22
|
-
p_next = pagy.next
|
18
|
+
def pagy_nav(pagy, id: nil, aria_label: nil, **vars)
|
19
|
+
id = %( id="#{id}") if id
|
20
|
+
a = pagy_anchor(pagy)
|
23
21
|
|
24
|
-
html =
|
25
|
-
|
26
|
-
%(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
|
27
|
-
else
|
28
|
-
%(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> )
|
29
|
-
end
|
22
|
+
html = %(<nav#{id} class="pagy nav" #{nav_aria_label(pagy, aria_label:)}>#{
|
23
|
+
prev_a(pagy, a)})
|
30
24
|
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
31
25
|
html << case item
|
32
|
-
when Integer
|
33
|
-
|
34
|
-
when
|
35
|
-
|
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}"
|
36
34
|
end
|
37
35
|
end
|
38
|
-
html <<
|
39
|
-
%(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
|
40
|
-
else
|
41
|
-
%(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>)
|
42
|
-
end
|
43
|
-
html << %(</nav>)
|
36
|
+
html << %(#{next_a(pagy, a)}</nav>)
|
44
37
|
end
|
45
38
|
|
46
39
|
# Return examples: "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total"
|
47
|
-
def pagy_info(pagy,
|
48
|
-
|
40
|
+
def pagy_info(pagy, id: nil, item_name: nil)
|
41
|
+
id = %( id="#{id}") if id
|
49
42
|
p_count = pagy.count
|
50
|
-
key = if
|
51
|
-
|
52
|
-
|
43
|
+
key = if p_count.zero?
|
44
|
+
'pagy.info.no_items'
|
45
|
+
elsif pagy.pages == 1
|
46
|
+
'pagy.info.single_page'
|
47
|
+
else
|
48
|
+
'pagy.info.multiple_pages'
|
53
49
|
end
|
54
50
|
|
55
|
-
%(<span#{
|
56
|
-
pagy_t key, item_name: item_name || pagy_t(
|
51
|
+
%(<span#{id} class="pagy info">#{
|
52
|
+
pagy_t key, item_name: item_name || pagy_t('pagy.item_name', count: p_count),
|
57
53
|
count: p_count, from: pagy.from, to: pagy.to
|
58
54
|
}</span>)
|
59
55
|
end
|
60
56
|
|
61
|
-
# Return a performance optimized
|
57
|
+
# Return a performance optimized lambda to generate the HTML anchor element (a tag)
|
62
58
|
# Benchmarked on a 20 link nav: it is ~22x faster and uses ~18x less memory than rails' link_to
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
left, right = %(<a href="#{pagy_url_for
|
67
|
-
|
68
|
-
lambda do |page, text = pagy.label_for(page),
|
69
|
-
%(#{
|
70
|
-
|
71
|
-
|
72
|
-
else ''
|
73
|
-
end } #{extra_attrs}>#{text}</a>)
|
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>)
|
74
68
|
end
|
75
69
|
end
|
76
70
|
|
@@ -79,5 +73,28 @@ class Pagy
|
|
79
73
|
def pagy_t(key, opts = {})
|
80
74
|
Pagy::I18n.translate(@pagy_locale ||= nil, key, opts)
|
81
75
|
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def nav_aria_label(pagy, aria_label: nil)
|
80
|
+
aria_label ||= pagy_t('pagy.aria_label.nav', count: pagy.pages)
|
81
|
+
%(aria-label="#{aria_label}")
|
82
|
+
end
|
83
|
+
|
84
|
+
def prev_a(pagy, a, text: pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'))
|
85
|
+
if (p_prev = pagy.prev)
|
86
|
+
a.(p_prev, text, aria_label:)
|
87
|
+
else
|
88
|
+
%(<a role="link" aria-disabled="true" aria-label="#{aria_label}">#{text}</a>)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def next_a(pagy, a, text: pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.next'))
|
93
|
+
if (p_next = pagy.next)
|
94
|
+
a.(p_next, text, aria_label:)
|
95
|
+
else
|
96
|
+
%(<a role="link" aria-disabled="true" aria-label="#{aria_label}">#{text}</a>)
|
97
|
+
end
|
98
|
+
end
|
82
99
|
end
|
83
100
|
end
|
data/lib/pagy/i18n.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# See Pagy::I18n API documentation https://ddnexus.github.io/pagy/api/i18n
|
1
|
+
# See Pagy::I18n API documentation https://ddnexus.github.io/pagy/docs/api/i18n
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'yaml'
|
@@ -94,7 +94,9 @@ class Pagy
|
|
94
94
|
# the :one_other RULE is the default for locales missing from this list
|
95
95
|
LOCALE = Hash.new(RULE[:one_other]).tap do |hash|
|
96
96
|
hash['ar'] = RULE[:arabic]
|
97
|
+
hash['be'] = RULE[:east_slavic]
|
97
98
|
hash['bs'] = RULE[:east_slavic]
|
99
|
+
hash['ckb'] = RULE[:other]
|
98
100
|
hash['cs'] = RULE[:west_slavic]
|
99
101
|
hash['id'] = RULE[:other]
|
100
102
|
hash['fr'] = RULE[:one_upto_two_other]
|
@@ -105,10 +107,9 @@ class Pagy
|
|
105
107
|
hash['pl'] = RULE[:polish]
|
106
108
|
hash['ru'] = RULE[:east_slavic]
|
107
109
|
hash['sr'] = RULE[:east_slavic]
|
108
|
-
hash['sv'] = RULE[:one_two_other]
|
109
|
-
hash['sv-SE'] = RULE[:one_two_other]
|
110
110
|
hash['tr'] = RULE[:other]
|
111
111
|
hash['uk'] = RULE[:east_slavic]
|
112
|
+
hash['vi'] = RULE[:other]
|
112
113
|
hash['zh-CN'] = RULE[:other]
|
113
114
|
hash['zh-HK'] = RULE[:other]
|
114
115
|
hash['zh-TW'] = RULE[:other]
|
data/lib/pagy/url_helpers.rb
CHANGED
@@ -6,33 +6,21 @@ class Pagy
|
|
6
6
|
# Return the URL for the page, relying on the params method and Rack by default.
|
7
7
|
# It supports all Rack-based frameworks (Sinatra, Padrino, Rails, ...).
|
8
8
|
# For non-rack environments you can use the standalone extra
|
9
|
-
def pagy_url_for(pagy, page, absolute:
|
10
|
-
vars
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
query_string = "?#{Rack::Utils.build_nested_query(pagy_deprecated_params(pagy, params))}" # remove in 6.0
|
18
|
-
# params = pagy.params.call(params) if pagy.params.is_a?(Proc) # add in 6.0
|
19
|
-
# query_string = "?#{Rack::Utils.build_nested_query(params)}" # add in 6.0
|
20
|
-
"#{request.base_url if absolute}#{request.path}#{query_string}#{vars[:fragment]}"
|
9
|
+
def pagy_url_for(pagy, page, absolute: false, **_)
|
10
|
+
vars = pagy.vars
|
11
|
+
query_params = request.GET.clone
|
12
|
+
query_params.merge!(vars[:params].transform_keys(&:to_s)) if vars[:params].is_a?(Hash)
|
13
|
+
pagy_set_query_params(page, vars, query_params)
|
14
|
+
query_params = vars[:params].(query_params) if vars[:params].is_a?(Proc)
|
15
|
+
query_string = "?#{Rack::Utils.build_nested_query(query_params)}"
|
16
|
+
"#{request.base_url if absolute}#{vars[:request_path] || request.path}#{query_string}#{vars[:fragment]}"
|
21
17
|
end
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
pagy.params.call(params)
|
29
|
-
elsif respond_to?(:pagy_massage_params) # deprecated code
|
30
|
-
Warning.warn '[PAGY WARNING] The pagy_massage_params method has been deprecated and it will be ignored from version 6. ' \
|
31
|
-
'Set the :params variable to a Proc with the same code as the pagy_massage_params method.'
|
32
|
-
pagy_massage_params(params)
|
33
|
-
else
|
34
|
-
params # no massage params
|
35
|
-
end
|
19
|
+
# Add the page and items params
|
20
|
+
# Overridable by the jsonapi extra
|
21
|
+
def pagy_set_query_params(page, vars, query_params)
|
22
|
+
query_params[vars[:page_param].to_s] = page
|
23
|
+
query_params[vars[:items_param].to_s] = vars[:items] if vars[:items_extra]
|
36
24
|
end
|
37
25
|
end
|
38
26
|
end
|