pagy 3.8.0 → 4.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/lib/config/pagy.rb +36 -25
  4. data/lib/javascripts/pagy.js +104 -93
  5. data/lib/locales/ar.yml +26 -0
  6. data/lib/locales/bg.yml +2 -2
  7. data/lib/locales/bs.yml +24 -0
  8. data/lib/locales/ca.yml +2 -2
  9. data/lib/locales/cs.yml +22 -0
  10. data/lib/locales/da.yml +2 -2
  11. data/lib/locales/de.yml +2 -2
  12. data/lib/locales/en.yml +2 -2
  13. data/lib/locales/es.yml +2 -2
  14. data/lib/locales/fr.yml +2 -2
  15. data/lib/locales/hr.yml +24 -0
  16. data/lib/locales/id.yml +2 -2
  17. data/lib/locales/it.yml +2 -2
  18. data/lib/locales/ja.yml +2 -2
  19. data/lib/locales/km.yml +2 -2
  20. data/lib/locales/ko.yml +2 -2
  21. data/lib/locales/nb.yml +2 -2
  22. data/lib/locales/nl.yml +2 -2
  23. data/lib/locales/pl.yml +2 -2
  24. data/lib/locales/pt-BR.yml +2 -2
  25. data/lib/locales/pt.yml +22 -0
  26. data/lib/locales/ru.yml +2 -2
  27. data/lib/locales/sr.yml +23 -0
  28. data/lib/locales/sv-SE.yml +2 -2
  29. data/lib/locales/sv.yml +2 -2
  30. data/lib/locales/sw.yml +22 -0
  31. data/lib/locales/tr.yml +2 -2
  32. data/lib/locales/uk.yml +24 -0
  33. data/lib/locales/utils/i18n.rb +3 -11
  34. data/lib/locales/utils/loader.rb +7 -10
  35. data/lib/locales/utils/p11n.rb +49 -17
  36. data/lib/locales/zh-CN.yml +2 -2
  37. data/lib/locales/zh-HK.yml +2 -2
  38. data/lib/locales/zh-TW.yml +3 -3
  39. data/lib/pagy.rb +50 -26
  40. data/lib/pagy/backend.rb +5 -3
  41. data/lib/pagy/console.rb +21 -0
  42. data/lib/pagy/countless.rb +13 -10
  43. data/lib/pagy/deprecation.rb +27 -0
  44. data/lib/pagy/exceptions.rb +7 -2
  45. data/lib/pagy/extras/arel.rb +4 -3
  46. data/lib/pagy/extras/array.rb +4 -3
  47. data/lib/pagy/extras/bootstrap.rb +61 -30
  48. data/lib/pagy/extras/bulma.rb +60 -38
  49. data/lib/pagy/extras/countless.rb +7 -8
  50. data/lib/pagy/extras/elasticsearch_rails.rb +28 -17
  51. data/lib/pagy/extras/foundation.rb +61 -32
  52. data/lib/pagy/extras/headers.rb +13 -9
  53. data/lib/pagy/extras/i18n.rb +11 -5
  54. data/lib/pagy/extras/items.rb +21 -34
  55. data/lib/pagy/extras/materialize.rb +58 -35
  56. data/lib/pagy/extras/meilisearch.rb +55 -0
  57. data/lib/pagy/extras/metadata.rb +27 -21
  58. data/lib/pagy/extras/navs.rb +44 -20
  59. data/lib/pagy/extras/overflow.rb +52 -48
  60. data/lib/pagy/extras/searchkick.rb +27 -16
  61. data/lib/pagy/extras/semantic.rb +55 -30
  62. data/lib/pagy/extras/shared.rb +14 -15
  63. data/lib/pagy/extras/standalone.rb +62 -0
  64. data/lib/pagy/extras/support.rb +26 -9
  65. data/lib/pagy/extras/trim.rb +12 -11
  66. data/lib/pagy/extras/uikit.rb +54 -35
  67. data/lib/pagy/frontend.rb +64 -32
  68. metadata +16 -7
  69. data/lib/locales/README.md +0 -35
  70. data/lib/pagy/extras/pagy_search.rb +0 -18
  71. data/pagy.gemspec +0 -16
@@ -15,6 +15,6 @@ zh-CN:
15
15
  single_page: "显示<b>%{count}</b> 项%{item_name}"
16
16
  multiple_pages: "共 <b>%{count}</b> 项%{item_name},显示 <b>%{from}-%{to}</b>"
17
17
 
18
- combo_nav_js: " %{page_input} / %{pages} "
18
+ combo_nav_js: "<label>第 %{page_input} / %{pages} 页</label>"
19
19
 
20
- items_selector_js: "每页显示 %{items_input} 条%"
20
+ items_selector_js: "<label>每页显示 %{items_input} 条%</label>"
@@ -15,6 +15,6 @@ zh-HK:
15
15
  single_page: "顯示 <b>%{count}</b> %{item_name}"
16
16
  multiple_pages: "共 <b>%{count}</b> %{item_name},顯示 <b>%{from}-%{to}</b>"
17
17
 
18
- combo_nav_js: " %{page_input} / %{pages} "
18
+ combo_nav_js: "<label>第 %{page_input} / %{pages} 頁</label>"
19
19
 
20
- items_selector_js: "每頁顯示 %{items_input} 記錄"
20
+ items_selector_js: "<label>每頁顯示 %{items_input} 記錄</label>"
@@ -10,11 +10,11 @@ zh-TW:
10
10
  next: "下一頁&nbsp;&rsaquo;"
11
11
  gap: "&hellip;"
12
12
 
13
- combo_nav_js: "第 %{page_input} / %{pages} 頁"
14
-
15
13
  info:
16
14
  no_items: "沒找到項"
17
15
  single_page: "顯示 <b>%{count}</b> 項%{item_name}"
18
16
  multiple_pages: "共 <b>%{count}</b> 項%{item_name},顯示 <b>%{from}-%{to}</b>"
19
17
 
20
- items_selector_js: "每頁顯示 %{items_input} 項%{item_name}"
18
+ combo_nav_js: "<label>第 %{page_input} / %{pages} 頁</label>"
19
+
20
+ items_selector_js: "<label>每頁顯示 %{items_input} 項%{item_name}</label>"
data/lib/pagy.rb CHANGED
@@ -1,52 +1,76 @@
1
1
  # See Pagy API documentation: https://ddnexus.github.io/pagy/api/pagy
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  require 'pathname'
6
5
 
7
- class Pagy ; VERSION = '3.8.0'
6
+ # main class
7
+ class Pagy
8
+ VERSION = '4.10.1'
8
9
 
9
10
  # Root pathname to get the path of Pagy files like templates or dictionaries
10
- def self.root; @root ||= Pathname.new(__FILE__).dirname.freeze end
11
+ def self.root
12
+ @root ||= Pathname.new(__dir__).freeze
13
+ end
11
14
 
12
15
  # default vars
13
- VARS = { page:1, items:20, outset:0, size:[1,4,4,1], page_param: :page, params:{}, anchor:'', link_extra:'', i18n_key:'pagy.item_name', cycle:false }
16
+ VARS = { page: 1, items: 20, outset: 0, size: [1, 4, 4, 1], page_param: :page, # rubocop:disable Style/MutableConstant
17
+ params: {}, fragment: '', link_extra: '', i18n_key: 'pagy.item_name', cycle: false }
14
18
 
15
19
  attr_reader :count, :page, :items, :vars, :pages, :last, :offset, :from, :to, :prev, :next
16
20
 
21
+ INSTANCE_VARS_MIN = { count: 0, items: 1, page: 1, outset: 0 }.freeze
22
+
17
23
  # Merge and validate the options, do some simple arithmetic and set the instance variables
18
24
  def initialize(vars)
19
- @vars = VARS.merge(vars.delete_if{|_,v| v.nil? || v == '' }) # default vars + cleaned vars
20
- { count:0, items:1, outset:0, page:1 }.each do |k,min| # validate instance variables
21
- (@vars[k] && instance_variable_set(:"@#{k}", @vars[k].to_i) >= min) \
22
- or raise(VariableError.new(self), "expected :#{k} >= #{min}; got #{@vars[k].inspect}")
25
+ @vars = VARS.merge( vars.delete_if{|k,v| VARS.key?(k) && (v.nil? || v == '') } )
26
+ @vars[:fragment] = Pagy.deprecated_var(:anchor, @vars[:anchor], :fragment, @vars[:fragment]) if @vars[:anchor]
27
+
28
+ INSTANCE_VARS_MIN.each do |name,min|
29
+ raise VariableError.new(self), "expected :#{name} >= #{min}; got #{@vars[name].inspect}" \
30
+ unless @vars[name] && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
23
31
  end
24
- @pages = @last = [(@count.to_f / @items).ceil, 1].max # cardinal and ordinal meanings
25
- @page <= @last or raise(OverflowError.new(self), "expected :page in 1..#{@last}; got #{@page.inspect}")
26
- @offset = @items * (@page - 1) + @outset # pagination offset + outset (initial offset)
27
- @items = @count - ((@pages-1) * @items) if @page == @last && @count > 0 # adjust items for last non-empty page
28
- @from = @count == 0 ? 0 : @offset+1 - @outset # page begins from item
29
- @to = @count == 0 ? 0 : @offset + @items - @outset # page ends to item
30
- @prev = (@page-1 unless @page == 1) # nil if no prev page
31
- @next = @page == @last ? (1 if @vars[:cycle]) : @page+1 # nil if no next page, 1 if :cycle
32
+ @pages = @last = [(@count.to_f / @items).ceil, 1].max
33
+ raise OverflowError.new(self), "expected :page in 1..#{@last}; got #{@page.inspect}" \
34
+ if @page > @last
35
+
36
+ @offset = @items * (@page - 1) + @outset
37
+ @items = @count - ((@pages - 1) * @items) if @page == @last && @count.positive?
38
+ @from = @count.zero? ? 0 : @offset + 1 - @outset
39
+ @to = @count.zero? ? 0 : @offset + @items - @outset
40
+ @prev = (@page - 1 unless @page == 1)
41
+ @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
32
42
  end
33
43
 
34
44
  # Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
35
45
  def series(size=@vars[:size])
36
- (series = []) and size.empty? and return series
37
- 4.times{|i| (size[i]>=0 rescue nil) or raise(VariableError.new(self), "expected 4 items >= 0 in :size; got #{size.inspect}")}
38
- [*0..size[0], *@page-size[1]..@page+size[2], *@last-size[3]+1..@last+1].sort!.each_cons(2) do |a, b|
39
- if a<0 || a==b || a>@last # skip out of range and duplicates
40
- elsif a+1 == b; series.push(a) # no gap -> no additions
41
- elsif a+2 == b; series.push(a, a+1) # 1 page gap -> fill with missing page
42
- else series.push(a, :gap) # n page gap -> add gap
43
- end # skip the end boundary (last+1)
44
- end # shift the start boundary (0) and
45
- series.shift; series[series.index(@page)] = @page.to_s; series # convert the current page to String
46
+ return [] if size.empty?
47
+ raise VariableError.new(self), "expected 4 items >= 0 in :size; got #{size.inspect}" \
48
+ unless size.size == 4 && size.all?{ |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
49
+ # This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
50
+ left_gap_start = 1 + size[0]
51
+ left_gap_end = @page - size[1] - 1
52
+ right_gap_start = @page + size[2] + 1
53
+ right_gap_end = @last - size[3]
54
+ left_gap_end = right_gap_end if left_gap_end > right_gap_end
55
+ right_gap_start = left_gap_start if left_gap_start > right_gap_start
56
+ series = []
57
+ start = 1
58
+ if (left_gap_end - left_gap_start).positive?
59
+ series.push(*start..(left_gap_start - 1), :gap)
60
+ start = left_gap_end + 1
61
+ end
62
+ if (right_gap_end - right_gap_start).positive?
63
+ series.push(*start..(right_gap_start - 1), :gap)
64
+ start = right_gap_end + 1
65
+ end
66
+ series.push(*start..@last)
67
+ series[series.index(@page)] = @page.to_s
68
+ series
46
69
  end
47
70
 
48
71
  end
49
72
 
73
+ require 'pagy/deprecation'
50
74
  require 'pagy/backend'
51
75
  require 'pagy/frontend'
52
76
  require 'pagy/exceptions'
data/lib/pagy/backend.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # See Pagy::Backend API documentation: https://ddnexus.github.io/pagy/api/backend
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  class Pagy
@@ -8,16 +7,19 @@ class Pagy
8
7
 
9
8
  # See also the extras if you need specialized methods to paginate Arrays or other collections
10
9
 
11
- module Backend ; private # the whole module is private so no problem with including it in a controller
10
+
11
+ module Backend
12
+ private # the whole module is private so no problem with including it in a controller
12
13
 
13
14
  # Return Pagy object and items
14
15
  def pagy(collection, vars={})
15
16
  pagy = Pagy.new(pagy_get_vars(collection, vars))
16
- return pagy, pagy_get_items(collection, pagy)
17
+ [ pagy, pagy_get_items(collection, pagy) ]
17
18
  end
18
19
 
19
20
  # Sub-method called only by #pagy: here for easy customization of variables by overriding
20
21
  def pagy_get_vars(collection, vars)
22
+ pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
21
23
  vars[:count] ||= (c = collection.count(:all)).is_a?(Hash) ? c.size : c
22
24
  vars[:page] ||= params[ vars[:page_param] || VARS[:page_param] ]
23
25
  vars
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pagy' # so you can require just the extra in the console
4
+ require 'pagy/extras/standalone'
5
+
6
+ class Pagy
7
+ # include Pagy::Console in irb/rails console for a ready to use pagy environment
8
+ module Console
9
+ def self.included(main)
10
+ main.include(Backend)
11
+ main.include(Frontend)
12
+ VARS[:url] = 'http://www.example.com/subdir'
13
+ end
14
+
15
+ def pagy_extras(*extras)
16
+ extras.each {|extra| require "pagy/extras/#{extra}"}
17
+ puts "Required extras: #{extras.map(&:inspect).join(', ')}"
18
+ end
19
+ end
20
+
21
+ end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'pagy'
@@ -7,25 +6,29 @@ class Pagy
7
6
 
8
7
  class Countless < Pagy
9
8
 
9
+ INSTANCE_VARS_MIN = { items: 1, page: 1, outset: 0 }.freeze
10
+
10
11
  # Merge and validate the options, do some simple arithmetic and set a few instance variables
11
- def initialize(vars={})
12
+ def initialize(vars={}) # rubocop:disable Lint/MissingSuper
12
13
  @vars = VARS.merge(vars.delete_if{|_,v| v.nil? || v == '' }) # default vars + cleaned vars (can be overridden)
13
- { items:1, outset:0, page:1 }.each do |k,min| # validate instance variables
14
- (@vars[k] && instance_variable_set(:"@#{k}", @vars[k].to_i) >= min) \
15
- or raise(VariableError.new(self), "expected :#{k} >= #{min}; got #{@vars[k].inspect}")
14
+ INSTANCE_VARS_MIN.each do |k,min| # validate instance variables
15
+ raise VariableError.new(self), "expected :#{k} >= #{min}; got #{@vars[k].inspect}" \
16
+ unless @vars[k] && instance_variable_set(:"@#{k}", @vars[k].to_i) >= min
16
17
  end
17
18
  @offset = @items * (@page - 1) + @outset # pagination offset + outset (initial offset)
18
19
  end
19
20
 
20
21
  # Finalize the instance variables based on the fetched items
21
22
  def finalize(fetched)
22
- fetched == 0 && @page > 1 and raise(OverflowError.new(self), "page #{@page} got no items")
23
+ raise OverflowError.new(self), "page #{@page} got no items" \
24
+ if fetched.zero? && @page > 1
25
+
23
26
  @pages = @last = (fetched > @items ? @page + 1 : @page) # set the @pages and @last
24
- @items = fetched if fetched < @items && fetched > 0 # adjust items for last non-empty page
25
- @from = fetched == 0 ? 0 : @offset+1 - @outset # page begins from item
26
- @to = fetched == 0 ? 0 : @offset + @items - @outset # page ends to item
27
+ @items = fetched if fetched < @items && fetched.positive? # adjust items for last non-empty page
28
+ @from = fetched.zero? ? 0 : @offset + 1 - @outset # page begins from item
29
+ @to = fetched.zero? ? 0 : @offset + @items - @outset # page ends to item
27
30
  @prev = (@page-1 unless @page == 1) # nil if no prev page
28
- @next = @page == @last ? (1 if @vars[:cycle]) : @page+1 # nil if no next page, 1 if :cycle
31
+ @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1 # nil if no next page, 1 if :cycle
29
32
  self
30
33
  end
31
34
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+ class Pagy
3
+ class << self
4
+
5
+ # deprecated variables
6
+ def deprecated_var(var, val, new_var, new_val)
7
+ value = val || new_val
8
+ Warning.warn %([PAGY WARNING] deprecated use of '#{var}' var will not be supported in 5.0! Use '#{new_var}: #{value.inspect}' instead.)
9
+ value
10
+ end
11
+
12
+ # deprecated pagy_url_for argument order
13
+ def deprecated_order(pagy, page)
14
+ Warning.warn %([PAGY WARNING] inverted use of pagy/page in pagy_url_for will not be supported in 5.0! Use pagy_url_for(pagy, page) instead.)
15
+ [page, pagy]
16
+ end
17
+
18
+
19
+ # deprecated posiitioal arguments
20
+ def deprecated_arg(arg, val, new_key, new_val)
21
+ value = val || new_val # we use the new_val if present
22
+ Warning.warn %([PAGY WARNING] deprecated use of positional '#{arg}' arg will not be supported in 5.0! Use only the keyword arg '#{new_key}: #{value.inspect}' instead.)
23
+ value
24
+ end
25
+
26
+ end
27
+ end
@@ -1,15 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pagy
2
4
 
5
+ # generic variable error
3
6
  class VariableError < ArgumentError
4
7
  attr_reader :pagy
5
8
 
6
9
  def initialize(pagy)
10
+ super
7
11
  @pagy = pagy
8
12
  end
9
13
 
10
14
  def variable
11
- message =~ /expected :([\w]+)/
12
- $1.to_sym if $1
15
+ message =~ /expected :(\w+)/
16
+ Regexp.last_match(1)&.to_sym
13
17
  end
14
18
 
15
19
  def value
@@ -17,6 +21,7 @@ class Pagy
17
21
  end
18
22
  end
19
23
 
24
+ # specific overflow error
20
25
  class OverflowError < VariableError; end
21
26
 
22
27
  end
@@ -1,16 +1,17 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/arel
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  class Pagy
6
- module Backend ; private
5
+ module Backend
6
+ private
7
7
 
8
8
  def pagy_arel(collection, vars={})
9
9
  pagy = Pagy.new(pagy_arel_get_vars(collection, vars))
10
- return pagy, pagy_get_items(collection, pagy)
10
+ [ pagy, pagy_get_items(collection, pagy) ]
11
11
  end
12
12
 
13
13
  def pagy_arel_get_vars(collection, vars)
14
+ pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
14
15
  vars[:count] ||= pagy_arel_count(collection)
15
16
  vars[:page] ||= params[ vars[:page_param] || VARS[:page_param] ]
16
17
  vars
@@ -1,19 +1,20 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/array
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  class Pagy
6
5
  # Add specialized backend methods to paginate array collections
7
- module Backend ; private
6
+ module Backend
7
+ private
8
8
 
9
9
  # Return Pagy object and items
10
10
  def pagy_array(array, vars={})
11
11
  pagy = Pagy.new(pagy_array_get_vars(array, vars))
12
- return pagy, array[pagy.offset, pagy.items]
12
+ [ pagy, array[pagy.offset, pagy.items] ]
13
13
  end
14
14
 
15
15
  # Sub-method called only by #pagy_array: here for easy customization of variables by overriding
16
16
  def pagy_array_get_vars(array, vars)
17
+ pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
17
18
  vars[:count] ||= array.size
18
19
  vars[:page] ||= params[ vars[:page_param] || VARS[:page_param] ]
19
20
  vars
@@ -1,5 +1,4 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bootstrap
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  require 'pagy/extras/shared'
@@ -8,48 +7,80 @@ class Pagy
8
7
  module Frontend
9
8
 
10
9
  # Pagination for bootstrap: it returns the html with the series of links to the pages
11
- def pagy_bootstrap_nav(pagy)
12
- link, p_prev, p_next = pagy_link_proc(pagy, 'class="page-link"'), pagy.prev, pagy.next
10
+ def pagy_bootstrap_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="page-link" #{link_extra}))
13
13
 
14
- html = EMPTY + (p_prev ? %(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
15
- : %(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.prev')}</a></li>))
14
+ html = +%(<nav#{p_id} class="pagy-bootstrap-nav" aria-label="pager"><ul class="pagination">)
15
+ html << pagy_bootstrap_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); %(<li class="page-item">#{link.call item}</li>) # page link
18
- elsif item.is_a?(String) ; %(<li class="page-item active">#{link.call item}</li>) # active page
19
- elsif item == :gap ; %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.gap')}</a></li>) # page gap
17
+ html << case item
18
+ when Integer then %(<li class="page-item">#{link.call item}</li>)
19
+ when String then %(<li class="page-item active">#{link.call item}</li>)
20
+ when :gap then %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
20
21
  end
21
22
  end
22
- html << (p_next ? %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
23
- : %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.next')}</a></li>))
24
- %(<nav class="pagy-bootstrap-nav" role="navigation" aria-label="pager"><ul class="pagination">#{html}</ul></nav>)
23
+ html << pagy_bootstrap_next_html(pagy, link)
24
+ html << %(</ul></nav>)
25
25
  end
26
26
 
27
27
  # Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.nav javascript
28
- def pagy_bootstrap_nav_js(pagy, id=pagy_id)
29
- link, p_prev, p_next = pagy_link_proc(pagy, 'class="page-link"'), pagy.prev, pagy.next
30
- tags = { 'before' => p_prev ? %(<ul class="pagination"><li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
31
- : %(<ul class="pagination"><li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.prev')}</a></li>),
28
+ def pagy_bootstrap_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="page-link" #{link_extra}))
32
+ tags = { 'before' => %(<ul class="pagination">#{pagy_bootstrap_prev_html pagy, link}),
32
33
  'link' => %(<li class="page-item">#{mark = link.call(PAGE_PLACEHOLDER)}</li>),
33
34
  'active' => %(<li class="page-item active">#{mark}</li>),
34
- 'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.gap')}</a></li>),
35
- 'after' => p_next ? %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li></ul>)
36
- : %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.next')}</a></li></ul>) }
37
- %(<nav id="#{id}" class="pagy-bootstrap-nav-js" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(:nav, id, tags, pagy.sequels, defined?(TRIM) && pagy.vars[:page_param])})
35
+ 'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>),
36
+ 'after' => %(#{pagy_bootstrap_next_html pagy, link}</ul>) }
37
+
38
+ %(<nav#{p_id} class="pagy-njs pagy-bootstrap-nav-js" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
38
39
  end
39
40
 
40
41
  # Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
41
- def pagy_bootstrap_combo_nav_js(pagy, id=pagy_id)
42
- link, p_prev, p_next, p_page, p_pages = pagy_link_proc(pagy), pagy.prev, pagy.next, pagy.page, pagy.pages
43
-
44
- html = %(<nav id="#{id}" class="pagy-bootstrap-combo-nav-js pagination" role="navigation" aria-label="pager">) + %(<div class="btn-group" role="group">)
45
- html << (p_prev ? link.call(p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous" class="prev btn btn-primary"')
46
- : %(<a class="prev btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.prev')}</a>))
47
- input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" class="text-primary" style="padding: 0; border: none; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
48
- html << %(<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)}</div>)
49
- html << (p_next ? link.call(p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"')
50
- : %(<a class="next btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.next')}</a>))
51
- html << %(</div></nav>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
42
+ def pagy_bootstrap_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
43
+ pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
44
+ p_id = %( id="#{pagy_id}") if pagy_id
45
+ link = pagy_link_proc(pagy, link_extra: link_extra)
46
+ p_page = pagy.page
47
+ p_pages = pagy.pages
48
+ input = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" class="text-primary" style="padding: 0; border: none; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
49
+
50
+ %(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination" aria-label="pager"><div class="btn-group" role="group" #{
51
+ pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
52
+ }>#{
53
+ if (p_prev = pagy.prev)
54
+ link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous" class="prev btn btn-primary"'
55
+ else
56
+ %(<a class="prev btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.prev')}</a>)
57
+ end
58
+ }<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
59
+ if (p_next = pagy.next)
60
+ link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"'
61
+ else
62
+ %(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next' }</a>)
63
+ end
64
+ }</div></nav>)
52
65
  end
53
66
 
67
+ private
68
+
69
+ def pagy_bootstrap_prev_html(pagy, link)
70
+ if (p_prev = pagy.prev)
71
+ %(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
72
+ else
73
+ %(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.prev'}</a></li>)
74
+ end
75
+ end
76
+
77
+ def pagy_bootstrap_next_html(pagy, link)
78
+ if (p_next = pagy.next)
79
+ %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
80
+ else
81
+ %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.next'}</a></li>)
82
+ end
83
+ end
84
+
54
85
  end
55
86
  end