pagy 4.0.0 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,36 +1,42 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/metadata
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  class Pagy
6
5
  # Add a specialized backend method for pagination metadata
7
- module Backend ; private
6
+ module Backend
7
+ private
8
8
 
9
- METADATA = [ :scaffold_url, :first_url, :prev_url, :page_url, :next_url, :last_url,
10
- :count, :page, :items, :vars, :pages, :last, :from, :to, :prev, :next, :series ]
11
- METADATA << :sequels if VARS.key?(:steps) # :steps gets defined along with the #sequels method
9
+ METADATA = %i[ scaffold_url first_url prev_url page_url next_url last_url
10
+ count page items vars pages last from to prev next series
11
+ ].tap do |metadata|
12
+ metadata << :sequels if VARS.key?(:steps) # :steps gets defined along with the #sequels method
13
+ end.freeze
12
14
 
13
15
  VARS[:metadata] = METADATA.dup
14
16
 
15
17
  include Helpers
16
18
 
17
- def pagy_metadata(pagy, url=false)
18
- names = pagy.vars[:metadata]
19
- (unknown = names - METADATA).empty? or raise(VariableError.new(pagy), "unknown metadata #{unknown.inspect}")
20
- scaffold_url = pagy_url_for(PAGE_PLACEHOLDER, pagy, url)
21
- metadata = {}
22
- names.each do |key|
23
- metadata[key] = case key
24
- when :scaffold_url ; scaffold_url
25
- when :first_url ; scaffold_url.sub(PAGE_PLACEHOLDER, 1.to_s)
26
- when :prev_url ; scaffold_url.sub(PAGE_PLACEHOLDER, pagy.prev.to_s)
27
- when :page_url ; scaffold_url.sub(PAGE_PLACEHOLDER, pagy.page.to_s)
28
- when :next_url ; scaffold_url.sub(PAGE_PLACEHOLDER, pagy.next.to_s)
29
- when :last_url ; scaffold_url.sub(PAGE_PLACEHOLDER, pagy.last.to_s)
30
- else pagy.send(key)
31
- end
19
+ def pagy_metadata(pagy, deprecated_url=nil, absolute: nil)
20
+ absolute = Pagy.deprecated_arg(:url, deprecated_url, :absolute, absolute) if deprecated_url
21
+ names = pagy.vars[:metadata]
22
+ unknown = names - METADATA
23
+ raise VariableError.new(pagy), "unknown metadata #{unknown.inspect}" \
24
+ unless unknown.empty?
25
+
26
+ scaffold_url = pagy_url_for(pagy, PAGE_PLACEHOLDER, absolute: absolute)
27
+ {}.tap do |metadata|
28
+ names.each do |key|
29
+ metadata[key] = case key
30
+ when :scaffold_url then scaffold_url
31
+ when :first_url then scaffold_url.sub(PAGE_PLACEHOLDER, 1.to_s)
32
+ when :prev_url then scaffold_url.sub(PAGE_PLACEHOLDER, pagy.prev.to_s)
33
+ when :page_url then scaffold_url.sub(PAGE_PLACEHOLDER, pagy.page.to_s)
34
+ when :next_url then scaffold_url.sub(PAGE_PLACEHOLDER, pagy.next.to_s)
35
+ when :last_url then scaffold_url.sub(PAGE_PLACEHOLDER, pagy.last.to_s)
36
+ else pagy.send(key)
37
+ end
38
+ end
32
39
  end
33
- metadata
34
40
  end
35
41
 
36
42
  end
@@ -1,5 +1,4 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/navs
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  require 'pagy/extras/shared'
@@ -8,31 +7,57 @@ class Pagy
8
7
  module Frontend
9
8
 
10
9
  # Javascript pagination: it returns a nav and a JSON tag used by the Pagy.nav javascript
11
- def pagy_nav_js(pagy, id=pagy_id)
12
- link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
13
- tags = { 'before' => p_prev ? %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
14
- : %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> ),
10
+ def pagy_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
11
+ pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
12
+ p_id = %( id="#{pagy_id}") if pagy_id
13
+ link = pagy_link_proc(pagy, link_extra: link_extra)
14
+ tags = { 'before' => pagy_nav_prev_html(pagy, link),
15
15
  'link' => %(<span class="page">#{link.call(PAGE_PLACEHOLDER)}</span> ),
16
16
  'active' => %(<span class="page active">#{pagy.page}</span> ),
17
- 'gap' => %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> ),
18
- 'after' => p_next ? %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
19
- : %(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>) }
20
- %(<nav id="#{id}" class="pagy-nav-js pagination" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
17
+ 'gap' => %(<span class="page gap">#{pagy_t 'pagy.nav.gap'}</span> ),
18
+ 'after' => pagy_nav_next_html(pagy, link) }
19
+
20
+ html = %(<nav#{p_id} class="pagy-njs pagy-nav-js pagination" role="navigation" aria-label="pager"></nav>)
21
+ html << pagy_json_tag(pagy, :nav, tags, pagy.sequels(steps))
21
22
  end
22
23
 
23
24
  # Javascript combo pagination: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
24
- def pagy_combo_nav_js(pagy, id=pagy_id)
25
- link, p_prev, p_next, p_page, p_pages = pagy_link_proc(pagy), pagy.prev, pagy.next, pagy.page, pagy.pages
26
-
27
- html = %(<nav id="#{id}" class="pagy-combo-nav-js pagination" role="navigation" aria-label="pager">)
28
- html << (p_prev ? %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
29
- : %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> ))
30
- input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
31
- html << %(<span class="pagy-combo-input" style="margin: 0 0.6rem;">#{pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)}</span> )
32
- html << (p_next ? %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
33
- : %(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>))
34
- html << %(</nav>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
25
+ def pagy_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
26
+ pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
27
+ p_id = %( id="#{pagy_id}") if pagy_id
28
+ link = pagy_link_proc(pagy, link_extra: link_extra)
29
+ p_page = pagy.page
30
+ p_pages = pagy.pages
31
+ input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
32
+
33
+ %(<nav#{p_id} class="pagy-combo-nav-js pagination" role="navigation" aria-label="pager">#{
34
+ pagy_nav_prev_html pagy, link
35
+ }<span class="pagy-combo-input" style="margin: 0 0.6rem;">#{
36
+ pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
37
+ }</span> #{
38
+ pagy_nav_next_html pagy, link
39
+ }</nav>#{
40
+ pagy_json_tag pagy, :combo_nav, p_page, pagy_marked_link(link)
41
+ })
35
42
  end
36
43
 
44
+ private
45
+
46
+ def pagy_nav_prev_html(pagy, link)
47
+ if (p_prev = pagy.prev)
48
+ %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
49
+ else
50
+ %(<span class="page prev disabled">#{pagy_t 'pagy.nav.prev'}</span> )
51
+ end
52
+ end
53
+
54
+ def pagy_nav_next_html(pagy, link)
55
+ if (p_next = pagy.next)
56
+ %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
57
+ else
58
+ %(<span class="page next disabled">#{pagy_t 'pagy.nav.next'}</span>)
59
+ end
60
+ end
61
+
37
62
  end
38
63
  end
@@ -1,10 +1,9 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/overflow
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  class Pagy
6
5
 
7
- module Overflow
6
+ module UseOverflowExtra
8
7
  VARS[:overflow] = :empty_page
9
8
 
10
9
  def overflow? = @overflow
@@ -19,12 +18,12 @@ class Pagy
19
18
  raise # same as without the extra
20
19
  when :last_page
21
20
  initial_page = @vars[:page] # save the very initial page (even after re-run)
22
- initialize(vars.merge!(page: @last)) # re-run with the last page
21
+ initialize vars.merge!(page: @last) # re-run with the last page
23
22
  @vars[:page] = initial_page # restore the inital page
24
23
  when :empty_page
25
24
  @offset = @items = @from = @to = 0 # vars relative to the actual page
26
25
  @prev = @last # prev relative to the actual page
27
- extend(Series) # special series for :empty_page
26
+ extend Series # special series for :empty_page
28
27
  else
29
28
  raise VariableError.new(self), "expected :overflow variable in [:last_page, :empty_page, :exception]; got #{@vars[:overflow].inspect}"
30
29
  end
@@ -34,33 +33,33 @@ class Pagy
34
33
  def series(size=@vars[:size])
35
34
  @page = @last # series for last page
36
35
  super(size).tap do |s| # call original series
37
- s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
38
- @page = @vars[:page] # restore the actual page
36
+ s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
37
+ @page = @vars[:page] # restore the actual page
39
38
  end
40
39
  end
41
40
  end
42
41
 
43
42
  end
44
- prepend Overflow
43
+ prepend UseOverflowExtra
45
44
 
46
45
 
47
46
  # support for Pagy::Countless
48
47
  if defined?(Pagy::Countless)
49
48
  class Countless
50
49
 
51
- module Overflow
50
+ module UseOverflowExtra
52
51
 
53
52
  def finalize(items)
54
53
  @overflow = false
55
54
  super
56
55
  rescue OverflowError
57
- @overflow = true # add the overflow flag
56
+ @overflow = true # add the overflow flag
58
57
  case @vars[:overflow]
59
58
  when :exception
60
- raise # same as without the extra
59
+ raise # same as without the extra
61
60
  when :empty_page
62
- @offset = @items = @from = @to = 0 # vars relative to the actual page
63
- @vars[:size] = [] # no page in the series
61
+ @offset = @items = @from = @to = 0 # vars relative to the actual page
62
+ @vars[:size] = [] # no page in the series
64
63
  self
65
64
  else
66
65
  raise VariableError.new(self), "expected :overflow variable in [:empty_page, :exception]; got #{@vars[:overflow].inspect}"
@@ -68,7 +67,7 @@ class Pagy
68
67
  end
69
68
 
70
69
  end
71
- prepend Overflow
70
+ prepend UseOverflowExtra
72
71
 
73
72
  end
74
73
  end
@@ -1,5 +1,4 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/searchkick
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  class Pagy
@@ -10,7 +9,7 @@ class Pagy
10
9
  # returns an array used to delay the call of #search
11
10
  # after the pagination variables are merged to the options
12
11
  # it also pushes to the same array an eventually called method
13
- def pagy_searchkick(term = "*", **options, &block)
12
+ def pagy_searchkick(term = '*', **options, &block)
14
13
  [self, term, options, block].tap do |args|
15
14
  args.define_singleton_method(:method_missing){|*a| args += a}
16
15
  end
@@ -27,7 +26,8 @@ class Pagy
27
26
  end
28
27
 
29
28
  # Add specialized backend methods to paginate Searchkick::Results
30
- module Backend ; private
29
+ module Backend
30
+ private
31
31
 
32
32
  # Return Pagy object and results
33
33
  def pagy_searchkick(pagy_search_args, vars={})
@@ -37,17 +37,19 @@ class Pagy
37
37
  options[:page] = vars[:page]
38
38
  results = model.search(term, **options, &block)
39
39
  vars[:count] = results.total_count
40
+
40
41
  pagy = Pagy.new(vars)
41
42
  # with :last_page overflow we need to re-run the method in order to get the hits
42
- if defined?(Pagy::Overflow) && pagy.overflow? && pagy.vars[:overflow] == :last_page
43
- return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page))
44
- end
45
- return pagy, called.empty? ? results : results.send(*called)
43
+ return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page)) \
44
+ if defined?(Pagy::UseOverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
45
+
46
+ [ pagy, called.empty? ? results : results.send(*called) ]
46
47
  end
47
48
 
48
49
  # Sub-method called only by #pagy_searchkick: here for easy customization of variables by overriding
49
50
  # the _collection argument is not available when the method is called
50
51
  def pagy_searchkick_get_vars(_collection, vars)
52
+ pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
51
53
  vars[:items] ||= VARS[:items]
52
54
  vars[:page] ||= (params[ vars[:page_param] || VARS[:page_param] ] || 1).to_i
53
55
  vars
@@ -1,5 +1,4 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/semantic
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  require 'pagy/extras/shared'
@@ -8,48 +7,75 @@ class Pagy
8
7
  module Frontend
9
8
 
10
9
  # Pagination for semantic: it returns the html with the series of links to the pages
11
- def pagy_semantic_nav(pagy)
12
- link, p_prev, p_next = pagy_link_proc(pagy, 'class="item"'), pagy.prev, pagy.next
10
+ def pagy_semantic_nav(pagy, pagy_id: nil, link_extra: '')
11
+ p_id = %( id="#{pagy_id}") if pagy_id
12
+ link = pagy_link_proc(pagy, link_extra: %(class="item" #{link_extra}"))
13
13
 
14
- html = (p_prev ? %(#{link.call p_prev, '<i class="left small chevron icon"></i>', 'aria-label="previous"'})
15
- : +%(<div class="item disabled"><i class="left small chevron icon"></i></div>))
14
+ html = +%(<div#{p_id} class="pagy-semantic-nav ui pagination menu" aria-label="pager">)
15
+ html << pagy_semantic_prev_html(pagy, link)
16
16
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
17
- html << if item.is_a?(Integer); %(#{link.call item}) # page link
18
- elsif item.is_a?(String) ; %(<a class="item active">#{item}</a>) # current page
19
- elsif item == :gap ; %(<div class="disabled item">...</div>) # page gap
17
+ html << case item
18
+ when Integer then link.call item # page link
19
+ when String then %(<a class="item active">#{item}</a>) # current page
20
+ when :gap then %(<div class="disabled item">#{pagy_t 'pagy.nav.gap'}</div>) # page gap
20
21
  end
21
22
  end
22
- html << (p_next ? %(#{link.call p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"'})
23
- : %(<div class="item disabled"><i class="right small chevron icon"></i></div>))
24
- %(<div class="pagy-semantic-nav ui pagination menu" aria-label="pager">#{html}</div>)
23
+ html << pagy_semantic_next_html(pagy, link)
24
+ html << %(</div>)
25
25
  end
26
26
 
27
27
  # Javascript pagination for semantic: it returns a nav and a JSON tag used by the Pagy.nav javascript
28
- def pagy_semantic_nav_js(pagy, id=pagy_id)
29
- link, p_prev, p_next = pagy_link_proc(pagy, 'class="item"'), pagy.prev, pagy.next
30
- tags = { 'before' => (p_prev ? %(#{link.call(p_prev, '<i class="left small chevron icon"></i>', 'aria-label="previous"')})
31
- : %(<div class="item disabled"><i class="left small chevron icon"></i></div>)),
32
- 'link' => %(#{link.call(PAGE_PLACEHOLDER)}),
28
+ def pagy_semantic_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
29
+ pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
30
+ p_id = %( id="#{pagy_id}") if pagy_id
31
+ link = pagy_link_proc(pagy, link_extra: %(class="item" #{link_extra}))
32
+ tags = { 'before' => pagy_semantic_prev_html(pagy, link),
33
+ 'link' => link.call(PAGE_PLACEHOLDER),
33
34
  'active' => %(<a class="item active">#{pagy.page}</a>),
34
35
  'gap' => %(<div class="disabled item">#{pagy_t('pagy.nav.gap')}</div>),
35
- 'after' => (p_next ? %(#{link.call(p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"')})
36
- : %(<div class="item disabled"><i class="right small chevron icon"></i></div>)) }
37
- %(<div id="#{id}" class="pagy-semantic-nav-js ui pagination menu" role="navigation" aria-label="pager"></div>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
36
+ 'after' => pagy_semantic_next_html(pagy, link) }
37
+
38
+ html = %(<div#{p_id} class="pagy-njs pagy-semantic-nav-js ui pagination menu" role="navigation" aria-label="pager"></div>)
39
+ html << pagy_json_tag(pagy, :nav, tags, pagy.sequels(steps))
38
40
  end
39
41
 
40
42
  # Combo pagination for semantic: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
41
- def pagy_semantic_combo_nav_js(pagy, id=pagy_id)
42
- link, p_prev, p_next, p_page, p_pages = pagy_link_proc(pagy, 'class="item"'), pagy.prev, pagy.next, pagy.page, pagy.pages
43
-
44
- html = %(<div id="#{id}" class="pagy-semantic-combo-nav-js ui compact menu" role="navigation" aria-label="pager">)
45
- html << (p_prev ? %(#{link.call p_prev, '<i class="left small chevron icon"></i>', 'aria-label="previous"'})
46
- : %(<div class="item disabled"><i class="left small chevron icon"></i></div>))
47
- input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem; margin: 0 0.3rem">)
48
- html << %(<div class="pagy-combo-input item">#{pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)}</div> )
49
- html << (p_next ? %(#{link.call p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"'})
50
- : %(<div class="item disabled"><i class="right small chevron icon"></i></div>))
51
- html << %(</div>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
43
+ def pagy_semantic_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
44
+ pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
45
+ p_id = %( id="#{pagy_id}") if pagy_id
46
+ link = pagy_link_proc(pagy, link_extra: %(class="item" #{link_extra}))
47
+ p_page = pagy.page
48
+ p_pages = pagy.pages
49
+ input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem; margin: 0 0.3rem">)
50
+
51
+ %(<div#{p_id} class="pagy-semantic-combo-nav-js ui compact menu" role="navigation" aria-label="pager">#{
52
+ pagy_semantic_prev_html pagy, link
53
+ }<div class="pagy-combo-input item">#{
54
+ pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
55
+ }</div> #{
56
+ pagy_semantic_next_html pagy, link
57
+ }</div>#{
58
+ pagy_json_tag pagy, :combo_nav, p_page, pagy_marked_link(link)
59
+ })
52
60
  end
53
61
 
62
+ private
63
+
64
+ def pagy_semantic_prev_html(pagy, link)
65
+ if (p_prev = pagy.prev)
66
+ link.call p_prev, '<i class="left small chevron icon"></i>', 'aria-label="previous"'
67
+ else
68
+ +%(<div class="item disabled"><i class="left small chevron icon"></i></div>)
69
+ end
70
+ end
71
+
72
+ def pagy_semantic_next_html(pagy, link)
73
+ if (p_next = pagy.next)
74
+ link.call p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"'
75
+ else
76
+ +%(<div class="item disabled"><i class="right small chevron icon"></i></div>)
77
+ end
78
+ end
79
+
54
80
  end
55
81
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'digest'
@@ -17,10 +16,13 @@ class Pagy
17
16
  # "350" => [1, 2, :gap, 17, 18, 19, "20", 21, 22, 23, :gap, 49, 50],
18
17
  # "550" => [1, 2, 3, :gap, 16, 17, 18, 19, "20", 21, 22, 23, 24, :gap, 48, 49, 50] }
19
18
  # Notice: if :steps is false it will use the single {0 => @vars[:size]} size
20
- def sequels
21
- steps = @vars[:steps] || {0 => @vars[:size]}
22
- steps.key?(0) or raise(VariableError.new(self), "expected :steps to define the 0 width; got #{steps.inspect}")
23
- sequels = {}; steps.each {|width, size| sequels[width.to_s] = series(size)}; sequels
19
+ def sequels(steps=nil)
20
+ steps ||= @vars[:steps] || {0 => @vars[:size]}
21
+ raise VariableError.new(self), "expected :steps to define the 0 width; got #{steps.inspect}" \
22
+ unless steps.key?(0)
23
+ {}.tap do |sequels|
24
+ steps.each {|width, size| sequels[width.to_s] = series(size)}
25
+ end
24
26
  end
25
27
 
26
28
  module Frontend
@@ -28,23 +30,22 @@ class Pagy
28
30
  if defined?(Oj)
29
31
  # it returns a script tag with the JSON-serialized args generated with the faster oj gem
30
32
  def pagy_json_tag(pagy, *args)
31
- args << ( defined?(Trim) && pagy.vars[:page_param] )
33
+ args << pagy.vars[:page_param] if pagy.vars[:enable_trim_extra]
32
34
  %(<script type="application/json" class="pagy-json">#{Oj.dump(args, mode: :strict)}</script>)
33
35
  end
34
36
  else
35
37
  require 'json'
36
38
  # it returns a script tag with the JSON-serialized args generated with the slower to_json
37
39
  def pagy_json_tag(pagy, *args)
38
- args << ( defined?(Trim) && pagy.vars[:page_param] )
40
+ args << pagy.vars[:page_param] if pagy.vars[:enable_trim_extra]
39
41
  %(<script type="application/json" class="pagy-json">#{args.to_json}</script>)
40
42
  end
41
43
  end
42
44
 
43
- # it returns the SHA1 (fastest on modern ruby) string used as default `id` attribute by all the `*_js` tags
44
- def pagy_id = "pagy-#{Digest::SHA1.hexdigest(caller(2..2)[0].split(':in')[0])}"
45
-
46
45
  # it returns the marked link to used by pagy.js
47
- def pagy_marked_link(link) = link.call(PAGE_PLACEHOLDER, '', 'style="display: none;"')
46
+ def pagy_marked_link(link)
47
+ link.call PAGE_PLACEHOLDER, '', 'style="display: none;"'
48
+ end
48
49
 
49
50
  end
50
51
 
@@ -0,0 +1,71 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/standalone
2
+ # frozen_string_literal: true
3
+
4
+ require 'uri'
5
+ class Pagy
6
+
7
+ # extracted from Rack::Utils and reformatted for rubocop
8
+ module QueryUtils
9
+ module_function
10
+ def escape(str)
11
+ URI.encode_www_form_component(str)
12
+ end
13
+ def build_nested_query(value, prefix = nil)
14
+ case value
15
+ when Array
16
+ value.map { |v| build_nested_query(v, "#{prefix}[]") }.join('&')
17
+ when Hash
18
+ value.map { |k, v| build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) }.delete_if(&:empty?).join('&')
19
+ when nil
20
+ prefix
21
+ else
22
+ raise ArgumentError, 'value must be a Hash' if prefix.nil?
23
+ "#{prefix}=#{escape(value)}"
24
+ end
25
+ end
26
+ end
27
+
28
+ module UseStandaloneExtra
29
+ # without any :url var it works exactly as the regular #pagy_url_for;
30
+ # with a defined :url variable it does not use rack/request
31
+ def pagy_url_for(pagy, page, deprecated_url=nil, absolute: nil)
32
+ absolute = Pagy.deprecated_arg(:url, deprecated_url, :absolute, absolute) if deprecated_url
33
+ pagy, page = Pagy.deprecated_order(pagy, page) if page.is_a?(Pagy)
34
+ p_vars = pagy.vars
35
+ if p_vars[:url]
36
+ url_string = p_vars[:url]
37
+ params = {}
38
+ else
39
+ url_string = "#{request.base_url if absolute}#{request.path}"
40
+ params = request.GET
41
+ end
42
+ params = params.merge(p_vars[:params])
43
+ params[p_vars[:page_param].to_s] = page
44
+ params[p_vars[:items_param].to_s] = p_vars[:items] if defined?(UseItemsExtra)
45
+ query_string = "?#{QueryUtils.build_nested_query(pagy_get_params(params))}" unless params.empty?
46
+ "#{url_string}#{query_string}#{p_vars[:fragment]}"
47
+ end
48
+ end
49
+ Helpers.prepend UseStandaloneExtra
50
+
51
+ # defines a dummy #params method if not already defined in the including module
52
+ module Backend
53
+ def self.included(controller)
54
+ controller.define_method(:params){{}} unless controller.method_defined?(:params)
55
+ end
56
+ end
57
+
58
+ # include Pagy::Console in irb/rails console for a ready to use pagy environment
59
+ module Console
60
+ def self.included(main)
61
+ main.include(Backend)
62
+ main.include(Frontend)
63
+ VARS[:url] = 'http://www.example.com/subdir'
64
+ end
65
+
66
+ def pagy_extras(*extras)
67
+ extras.each {|extra| require "pagy/extras/#{extra}"}
68
+ end
69
+ end
70
+
71
+ end