pagy 4.1.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,4 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/uikit
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  require 'pagy/extras/shared'
@@ -9,54 +8,80 @@ class Pagy
9
8
 
10
9
  # Pagination for uikit: it returns the html with the series of links to the pages
11
10
  def pagy_uikit_nav(pagy)
12
- link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
11
+ link = pagy_link_proc(pagy)
13
12
 
14
- previous_span = "<span uk-pagination-previous>#{pagy_t('pagy.nav.prev')}</span>"
15
- html = (p_prev ? %(<li>#{link.call p_prev, previous_span}</li>)
16
- : %(<li class="uk-disabled"><a href="#">#{previous_span}</a></li>))
13
+ html = %(<ul class="pagy-uikit-nav uk-pagination uk-flex-center">#{pagy_uikit_prev_html(pagy, link)})
17
14
  pagy.series.each do |item|
18
- html << if item.is_a?(Integer); %(<li>#{link.call item}</li>)
19
- elsif item.is_a?(String) ; %(<li class="uk-active"><span>#{item}</span></li>)
20
- elsif item == :gap ; %(<li class="uk-disabled"><span>#{pagy_t('pagy.nav.gap')}</span></li>)
15
+ html << case item
16
+ when Integer then %(<li>#{link.call item}</li>)
17
+ when String then %(<li class="uk-active"><span>#{item}</span></li>)
18
+ when :gap then %(<li class="uk-disabled"><span>#{pagy_t('pagy.nav.gap')}</span></li>)
21
19
  end
22
20
  end
23
- next_span = "<span uk-pagination-next>#{pagy_t('pagy.nav.next')}</span>"
24
- html << (p_next ? %(<li>#{link.call p_next, next_span}</li>)
25
- : %(<li class="uk-disabled"><a href="#">#{next_span}</a></li>))
26
- %(<ul class="pagy-uikit-nav uk-pagination uk-flex-center">#{html}</ul>)
21
+ html << pagy_uikit_next_html(pagy, link)
22
+ html << %(</ul>)
27
23
  end
28
24
 
29
25
  # Javascript pagination for uikit: it returns a nav and a JSON tag used by the Pagy.nav javascript
30
26
  def pagy_uikit_nav_js(pagy, id=pagy_id)
31
- link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
32
- previous_span = "<span uk-pagination-previous>#{pagy_t('pagy.nav.prev')}</span>"
33
- next_span = "<span uk-pagination-next>#{pagy_t('pagy.nav.next')}</span>"
34
- tags = { 'before' => p_prev ? %(<li>#{link.call p_prev, previous_span}</li>)
35
- : %(<li class="uk-disabled"><a href="#">#{previous_span}</a></li>),
27
+ link = pagy_link_proc(pagy)
28
+ tags = { 'before' => pagy_uikit_prev_html(pagy, link),
36
29
  'link' => %(<li>#{link.call(PAGE_PLACEHOLDER)}</li>),
37
30
  'active' => %(<li class="uk-active"><span>#{PAGE_PLACEHOLDER}</span></li>),
38
31
  'gap' => %(<li class="uk-disabled"><span>#{pagy_t('pagy.nav.gap')}</span></li>),
39
- 'after' => p_next ? %(<li>#{link.call p_next, next_span}</li>)
40
- : %(<li class="uk-disabled"><a href="#">#{next_span}</a></li>) }
41
- %(<ul id="#{id}" class="pagy-uikit-nav-js uk-pagination uk-flex-center"></ul>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
32
+ 'after' => pagy_uikit_next_html(pagy, link) }
33
+
34
+ html = %(<ul id="#{id}" class="pagy-uikit-nav-js uk-pagination uk-flex-center"></ul>)
35
+ html << pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)
42
36
  end
43
37
 
44
38
  # Javascript combo pagination for uikit: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
45
39
  def pagy_uikit_combo_nav_js(pagy, id=pagy_id)
46
- link, p_prev, p_next, p_page, p_pages = pagy_link_proc(pagy), pagy.prev, pagy.next, pagy.page, pagy.pages
40
+ link = pagy_link_proc(pagy)
41
+ p_page = pagy.page
42
+ p_pages = pagy.pages
43
+ input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" class="uk-input" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
44
+
45
+ %(<div id="#{id}" class="pagy-uikit-combo-nav-js uk-button-group">#{
46
+ if (p_prev = pagy.prev)
47
+ link.call p_prev, pagy_t('pagy.nav.prev'), 'class="uk-button uk-button-default"'
48
+ else
49
+ %(<button class="uk-button uk-button-default" disabled>#{pagy_t('pagy.nav.prev')}</button>)
50
+ end
51
+ }<div class="uk-text-middle uk-margin-left uk-margin-right">#{
52
+ pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)
53
+ }</div>#{
54
+ if (p_next = pagy.next)
55
+ link.call(p_next, pagy_t('pagy.nav.next'), 'class="uk-button uk-button-default"')
56
+ else
57
+ %(<button class="uk-button uk-button-default" disabled>#{pagy_t('pagy.nav.next')}</button>)
58
+ end
59
+ }</div>#{
60
+ pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))
61
+ })
62
+ end
47
63
 
48
- html = %(<div id="#{id}" class="pagy-uikit-combo-nav-js uk-button-group">)
49
- html = html + (p_prev ? link.call(p_prev, pagy_t('pagy.nav.prev'), 'class="uk-button uk-button-default"')
50
- : %(<button class="uk-button uk-button-default" disabled>#{pagy_t('pagy.nav.prev')}</button>))
51
64
 
52
- html << %(<div class="uk-text-middle uk-margin-left uk-margin-right">)
53
- input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" class="uk-input" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
54
- html << pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages) + '</div>'
55
65
 
56
- html << (p_next ? link.call(p_next, pagy_t('pagy.nav.next'), 'class="uk-button uk-button-default"')
57
- : %(<button class="uk-button uk-button-default" disabled>#{pagy_t('pagy.nav.next')}</button>))
66
+ private
67
+
68
+ def pagy_uikit_prev_html(pagy, link)
69
+ previous_span = %(<span uk-pagination-previous>#{pagy_t('pagy.nav.prev')}</span>)
70
+ if (p_prev = pagy.prev)
71
+ %(<li>#{link.call p_prev, previous_span}</li>)
72
+ else
73
+ %(<li class="uk-disabled"><a href="#">#{previous_span}</a></li>)
74
+ end
75
+ end
76
+
77
+ def pagy_uikit_next_html(pagy, link)
78
+ next_span = %(<span uk-pagination-next>#{pagy_t('pagy.nav.next')}</span>)
79
+ if (p_next = pagy.next)
80
+ %(<li>#{link.call p_next, next_span}</li>)
81
+ else
82
+ %(<li class="uk-disabled"><a href="#">#{next_span}</a></li>)
83
+ end
84
+ end
58
85
 
59
- html << %(</div>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
60
- end
61
86
  end
62
87
  end
data/lib/pagy/frontend.rb CHANGED
@@ -1,26 +1,27 @@
1
1
  # See Pagy::Frontend API documentation: https://ddnexus.github.io/pagy/api/frontend
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  require 'yaml'
6
5
 
7
6
  class Pagy
8
7
 
9
- PAGE_PLACEHOLDER = '__pagy_page__' # string used for search and replace, hardcoded also in the pagy.js file
8
+ PAGE_PLACEHOLDER = '__pagy_page__' # string used for search and replace, hardcoded also in the pagy.js file
10
9
 
11
10
  # I18n static hash loaded at startup, used as default alternative to the i18n gem.
12
11
  # see https://ddnexus.github.io/pagy/api/frontend#i18n
13
- I18n = eval(Pagy.root.join('locales', 'utils', 'i18n.rb').read) #rubocop:disable Security/Eval
12
+ I18n = eval Pagy.root.join('locales', 'utils', 'i18n.rb').read #rubocop:disable Security/Eval
14
13
 
15
14
  module Helpers
16
15
  # This works with all Rack-based frameworks (Sinatra, Padrino, Rails, ...)
17
- def pagy_url_for(page, pagy, url=false)
18
- p_vars = pagy.vars; params = request.GET.merge(p_vars[:params]); params[p_vars[:page_param].to_s] = page
16
+ def pagy_url_for(page, pagy, url=nil)
17
+ p_vars = pagy.vars
18
+ params = request.GET.merge(p_vars[:params])
19
+ params[p_vars[:page_param].to_s] = page
19
20
  "#{request.base_url if url}#{request.path}?#{Rack::Utils.build_nested_query(pagy_get_params(params))}#{p_vars[:anchor]}"
20
21
  end
21
22
 
22
23
  # Sub-method called only by #pagy_url_for: here for easy customization of params by overriding
23
- def pagy_get_params(params) params end
24
+ def pagy_get_params(params) = params
24
25
  end
25
26
 
26
27
  # All the code here has been optimized for performance: it may not look very pretty
@@ -31,42 +32,64 @@ class Pagy
31
32
 
32
33
  # Generic pagination: it returns the html with the series of links to the pages
33
34
  def pagy_nav(pagy)
34
- link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
35
+ link = pagy_link_proc(pagy)
36
+ p_prev = pagy.prev
37
+ p_next = pagy.next
35
38
 
36
- html = (p_prev ? %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
37
- : %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> ))
39
+ html = +%(<nav class="pagy-nav pagination" role="navigation" aria-label="pager">)
40
+ html << if p_prev
41
+ %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
42
+ else
43
+ %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> )
44
+ end
38
45
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
39
- html << if item.is_a?(Integer); %(<span class="page">#{link.call item}</span> ) # page link
40
- elsif item.is_a?(String) ; %(<span class="page active">#{item}</span> ) # current page
41
- elsif item == :gap ; %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> ) # page gap
46
+ html << case item
47
+ when Integer then %(<span class="page">#{link.call item}</span> ) # page link
48
+ when String then %(<span class="page active">#{item}</span> ) # current page
49
+ when :gap then %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> ) # page gap
42
50
  end
43
51
  end
44
- html << (p_next ? %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
45
- : %(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>))
46
- %(<nav class="pagy-nav pagination" role="navigation" aria-label="pager">#{html}</nav>)
52
+ html << if p_next
53
+ %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
54
+ else
55
+ %(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>)
56
+ end
57
+ html << %(</nav>)
47
58
  end
48
59
 
49
60
  # Return examples: "Displaying items 41-60 of 324 in total" of "Displaying Products 41-60 of 324 in total"
50
61
  def pagy_info(pagy, item_name=nil)
51
- key = if (count = pagy.count) == 0 ; 'pagy.info.no_items'
52
- else pagy.pages == 1 ? 'pagy.info.single_page' : 'pagy.info.multiple_pages'
53
- end
54
- pagy_t(key, item_name: item_name || pagy_t(pagy.vars[:i18n_key], count: count), count: count, from: pagy.from, to: pagy.to)
62
+ count = pagy.count
63
+ key = if count.zero? then 'pagy.info.no_items'
64
+ elsif pagy.pages == 1 then 'pagy.info.single_page'
65
+ else 'pagy.info.multiple_pages'
66
+ end
67
+ pagy_t key, item_name: item_name || pagy_t(pagy.vars[:i18n_key], count: count),
68
+ count: count,
69
+ from: pagy.from,
70
+ to: pagy.to
55
71
  end
56
72
 
57
73
  # Returns a performance optimized proc to generate the HTML links
58
74
  # Benchmarked on a 20 link nav: it is ~22x faster and uses ~18x less memory than rails' link_to
59
75
  def pagy_link_proc(pagy, link_extra='')
60
- p_prev, p_next = pagy.prev, pagy.next
61
- a, b = %(<a href="#{pagy_url_for(PAGE_PLACEHOLDER, pagy)}" #{pagy.vars[:link_extra]} #{link_extra}).split(PAGE_PLACEHOLDER, 2)
62
- lambda {|n, text=n, extra=''| "#{a}#{n}#{b}#{ if n == p_prev ; ' rel="prev"'
63
- elsif n == p_next ; ' rel="next"'
64
- else '' end } #{extra}>#{text}</a>"}
76
+ p_prev = pagy.prev
77
+ p_next = pagy.next
78
+ left, right = %(<a href="#{pagy_url_for(PAGE_PLACEHOLDER, pagy)}" #{pagy.vars[:link_extra]} #{link_extra}).split(PAGE_PLACEHOLDER, 2)
79
+ lambda do |num, text=num, extra=''|
80
+ "#{left}#{num}#{right}#{ case num
81
+ when p_prev then ' rel="prev"'
82
+ when p_next then ' rel="next"'
83
+ else ''
84
+ end } #{extra}>#{text}</a>"
85
+ end
65
86
  end
66
87
 
67
88
  # Similar to I18n.t: just ~18x faster using ~10x less memory
68
89
  # (@pagy_locale explicitly initilized in order to avoid warning)
69
- def pagy_t(key, **opts) = Pagy::I18n.t(@pagy_locale||=nil, key, **opts)
90
+ def pagy_t(key, **opts)
91
+ Pagy::I18n.t @pagy_locale||=nil, key, **opts
92
+ end
70
93
 
71
94
  end
72
95
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pagy
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Domizio Demichelis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-12 00:00:00.000000000 Z
11
+ date: 2021-04-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'Agnostic pagination in plain ruby: it works with any framework, ORM
14
14
  and DB type, with all kinds of collections, even pre-paginated, scopes, Arrays,