pagy 3.14.0 → 4.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49a179c68fcaeb3e1f5785db7c2faa3edb4da583ed521974876c87be9c81fba4
4
- data.tar.gz: 86e717c64839653506d14ac2a1f092f68c97e220ab8716c2e68419a375d2369f
3
+ metadata.gz: 8abadf0305f4adce1cb070d5de45822a38cfeb02b8e0e4389e33dee2f926ff0c
4
+ data.tar.gz: 1fe429839b5f704a62e70ace80cd2a2c851d8f8e2eee2dc89fe84dd18a1a5c2e
5
5
  SHA512:
6
- metadata.gz: 5d7222fe9b3445448cc1f7993b763bf8ca72a301c46090ee0884108c44a7aed935b35aebce2b814d9c1cf067a745293bcd069133a4879e744e1745134de44b7c
7
- data.tar.gz: 6d37feee515609f118f0612e255ce6cd52b9618b03451c724325f72409d6bea1b63059b211a97c60e5d23c17df9f5e41786dfbccc5dd0ea27a61329c4e4a0709
6
+ metadata.gz: 7ba816fa365290f6c7ca3850aca55cec280923f2a9f5340988373629526c6096206b31e66e053be8e7d968398b3d205468a9d4fad1978c6e984ef4b63f288197
7
+ data.tar.gz: 5caed0bfd335b497405a7665e8f74be8d99a9c8b2c1bf51090e49f99a60e68c770218d050815aaa82318d2b0b6891ed1f6ddc83ade1a88dd0d951da18280ceeb
data/lib/config/pagy.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- # Pagy initializer file (3.14.0)
4
+ # Pagy initializer file (4.0.0)
5
5
  # Customize only what you really need and notice that Pagy works also without any of the following lines.
6
6
  # Should you just cherry pick part of this file, please maintain the require-order of the extras
7
7
 
@@ -23,13 +23,18 @@
23
23
 
24
24
  # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
25
25
  # See https://ddnexus.github.io/pagy/extras/elasticsearch_rails
26
+ # default :pagy_search method: change only if you use
27
+ # also the searchkick extra that defines the same
28
+ # VARS[:elasticsearch_rails_search_method] = :pagy_search
26
29
  # require 'pagy/extras/elasticsearch_rails'
27
30
 
28
31
  # Searchkick extra: Paginate `Searchkick::Results` objects
29
32
  # See https://ddnexus.github.io/pagy/extras/searchkick
33
+ # default :pagy_search method: change only if you use
34
+ # also the elasticsearch_rails extra that defines the same
35
+ # VARS[:searchkick_search_method] = :pagy_search
30
36
  # require 'pagy/extras/searchkick'
31
37
 
32
-
33
38
  # Frontend Extras
34
39
 
35
40
  # Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination
@@ -2,7 +2,7 @@
2
2
 
3
3
  function Pagy(){}
4
4
 
5
- Pagy.version = '3.14.0';
5
+ Pagy.version = '4.0.0';
6
6
 
7
7
  Pagy.init = function(arg){
8
8
  var target = arg instanceof Event || arg === undefined ? document : arg,
@@ -0,0 +1,35 @@
1
+ # Pagy locales
2
+
3
+ ### Please, submit your translation!
4
+
5
+ If you find that some translation could be improved, please, create an issue.
6
+
7
+ If you are using pagy with some language missing from the dictionary files, please, submit your translation!
8
+
9
+ You can create a Pull Request for your language, and get all the help you need to correctly complete it. Here is a check list.
10
+
11
+ ### Check list for a new dictionary file:
12
+
13
+ - [ ] Find the pluralization rule for your language
14
+
15
+ - [ ] Find the locale file you need in the [list of pluralizations](https://github.com/svenfuchs/rails-i18n/tree/master/rails/pluralization) and check the pluralization rule in it. For example it is `::RailsI18n::Pluralization::OneOther.with_locale(:en)` for `en.rb`. Note the rule part i.e. `OneOther`. In pagy that translates to the symbol `:one_other`.
16
+
17
+ - [ ] If the pluralization rule of your language is not the `:one_other` default, confirm that the [p11n.rb](https://github.com/ddnexus/pagy/blob/master/lib/locales/utils/p11n.rb) file already defines the pluralization rule of your dictionary file:
18
+
19
+ - [ ] If the rule is not defined, you can either: a) Add the rule as a new rule/lambda entry in the `p11n` variable hash and relative tests or b) Just create an issue requesting the addition to the rule/lambda entry and tests.
20
+
21
+ - [ ] Add your language to the `plurals` hash in the file.
22
+
23
+ - [ ] add/edit the first line comment in the language rule in your dictionary file (e.g. `# :one_other pluralization ...`
24
+
25
+ - [ ] The mandatory pluralized entry in the dictionary file is the `item_name`. Please, provide all the plurals needed by your language. E.g. if your language uses the `:east_slavic` you should provide the plurals for `one`, `few`, `many` and `other`, if it uses `:one_other`, you should provide `one` and `other` plurals. If it uses `:other` you should only provide a single value. Look into other dictionary files to get some example. Ask if in doubt.
26
+
27
+ - [ ] The other entries in the dictionary file don't need any plural variant in most languages since the pluralization of the `item_name` in the sentence is enough. However, in some language, a whole sentence might need to be written in different ways for different counts. In that case you should add the different plurals for the sentence and the `count` will trigger the one that applies.
28
+
29
+ Feel free to ask for help in your Pull Request.
30
+
31
+ ### Useful Links
32
+
33
+ * [Pagy I18n Documentation](https://ddnexus.github.io/pagy/api/frontend#i18n)
34
+ * [I18n Extra](https://ddnexus.github.io/pagy/extras/i18n)
35
+
@@ -4,22 +4,15 @@
4
4
 
5
5
  # this file returns the I18n hash used as default alternative to the i18n gem
6
6
 
7
- Pagy::DEPRECATED_LOCALES = {'pt-br' =>'pt-BR', 'se' => 'sv-SE'}
8
-
9
7
  Hash.new{|h,_| h.first[1]}.tap do |i18n_hash| # first loaded locale used as default
10
8
  i18n_hash.define_singleton_method(:load) do |*load_args|
11
9
  # eval: we don't need to keep the loader proc in memory
12
10
  eval(Pagy.root.join('locales', 'utils', 'loader.rb').read).call(i18n_hash, *load_args) #rubocop:disable Security/Eval
13
11
  end
14
- i18n_hash.define_singleton_method(:t) do |locale, path, vars={}|
15
- if Pagy::DEPRECATED_LOCALES.key?(locale)
16
- new_locale = Pagy::DEPRECATED_LOCALES[locale]
17
- $stderr.puts("WARNING: the Pagy locale '#{locale}' is deprecated; use '#{new_locale}' instead")
18
- locale = new_locale
19
- end
12
+ i18n_hash.define_singleton_method(:t) do |locale, key, **opts|
20
13
  data, pluralize = self[locale]
21
- translate = data[path] || vars[:count] && data[path+=".#{pluralize.call(vars[:count])}"] or return %([translation missing: "#{path}"])
22
- translate.call(vars)
14
+ translate = data[key] || opts[:count] && data[key+=".#{pluralize.call(opts[:count])}"] or return %([translation missing: "#{key}"])
15
+ translate.call(opts)
23
16
  end
24
17
  i18n_hash.load(locale: 'en')
25
18
  end
@@ -20,11 +20,6 @@ flatten = lambda do |hash, key=''|
20
20
  lambda do |i18n, *args|
21
21
  i18n.clear
22
22
  args.each do |arg|
23
- if Pagy::DEPRECATED_LOCALES.key?(arg[:locale])
24
- new_locale = Pagy::DEPRECATED_LOCALES[arg[:locale]]
25
- $stderr.puts("WARNING: the Pagy locale '#{arg[:locale]}' is deprecated; use '#{new_locale}' instead")
26
- arg[:locale] = new_locale
27
- end
28
23
  arg[:filepath] ||= Pagy.root.join('locales', "#{arg[:locale]}.yml")
29
24
  arg[:pluralize] ||= plurals[arg[:locale]]
30
25
  hash = YAML.load(File.read(arg[:filepath], encoding: 'UTF-8')) #rubocop:disable Security/YAMLLoad
@@ -67,17 +67,14 @@ p11n = {
67
67
  # The default pluralization for locales not explicitly listed here
68
68
  # is the :one_other pluralization proc (used for English)
69
69
  plurals = Hash.new(p11n[:one_other]).tap do |hash|
70
- hash['bs'] = p11n[:east_slavic]
71
70
  hash['cs'] = p11n[:west_slavic]
72
71
  hash['id'] = p11n[:other]
73
72
  hash['fr'] = p11n[:one_upto_two_other]
74
- hash['hr'] = p11n[:east_slavic]
75
73
  hash['ja'] = p11n[:other]
76
74
  hash['km'] = p11n[:other]
77
75
  hash['ko'] = p11n[:other]
78
76
  hash['pl'] = p11n[:polish]
79
77
  hash['ru'] = p11n[:east_slavic]
80
- hash['sr'] = p11n[:east_slavic]
81
78
  hash['sv'] = p11n[:one_two_other]
82
79
  hash['sv-SE'] = p11n[:one_two_other]
83
80
  hash['tr'] = p11n[:other]
data/lib/pagy.rb CHANGED
@@ -4,10 +4,10 @@
4
4
 
5
5
  require 'pathname'
6
6
 
7
- class Pagy ; VERSION = '3.14.0'
7
+ class Pagy ; VERSION = '4.0.0'
8
8
 
9
9
  # Root pathname to get the path of Pagy files like templates or dictionaries
10
- def self.root; @root ||= Pathname.new(__FILE__).dirname.freeze end
10
+ def self.root = @root ||= Pathname.new(__FILE__).dirname.freeze
11
11
 
12
12
  # default vars
13
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 }
@@ -32,31 +32,18 @@ class Pagy ; VERSION = '3.14.0'
32
32
  end
33
33
 
34
34
  # Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
35
- def series(size=@vars[:size])
36
- return [] if size.empty?
37
- raise VariableError.new(self), "expected 4 items >= 0 in :size; got #{size.inspect}" \
38
- unless size.size == 4 && size.all?{ |num| num >= 0 rescue false }
39
- # This algorithm (backported from pagy 4.3) is up to ~5x faster and ~2.3x lighter than the previous one
40
- left_gap_start = 1 + size[0]
41
- left_gap_end = @page - size[1] - 1
42
- right_gap_start = @page + size[2] + 1
43
- right_gap_end = @last - size[3]
44
- left_gap_end = right_gap_end if left_gap_end > right_gap_end
45
- right_gap_start = left_gap_start if left_gap_start > right_gap_start
46
- series = []
47
- start = 1
48
- if (left_gap_end - left_gap_start) > 0
49
- series.push(*start..(left_gap_start - 1), :gap)
50
- start = left_gap_end + 1
35
+ 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; next # 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
51
46
  end
52
- if (right_gap_end - right_gap_start) > 0
53
- series.push(*start..(right_gap_start - 1), :gap)
54
- start = right_gap_end + 1
55
- end
56
- series.push(*start..@last)
57
- series[series.index(@page)] = @page.to_s
58
- series
59
- end
60
47
 
61
48
  end
62
49
 
@@ -8,7 +8,7 @@ class Pagy
8
8
  class Countless < Pagy
9
9
 
10
10
  # Merge and validate the options, do some simple arithmetic and set a few instance variables
11
- def initialize(vars={}) # rubocop:disable Lint/MissingSuper
11
+ def initialize(vars={}) # rubocop:disable Lint/MissingSuper
12
12
  @vars = VARS.merge(vars.delete_if{|_,v| v.nil? || v == '' }) # default vars + cleaned vars (can be overridden)
13
13
  { items:1, outset:0, page:1 }.each do |k,min| # validate instance variables
14
14
  (@vars[k] && instance_variable_set(:"@#{k}", @vars[k].to_i) >= min) \
@@ -11,8 +11,8 @@ class Pagy
11
11
  def pagy_bootstrap_nav(pagy)
12
12
  link, p_prev, p_next = pagy_link_proc(pagy, 'class="page-link"'), pagy.prev, pagy.next
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 = (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>))
16
16
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
17
17
  html << if item.is_a?(Integer); %(<li class="page-item">#{link.call item}</li>) # page link
18
18
  elsif item.is_a?(String) ; %(<li class="page-item active">#{link.call item}</li>) # active page
@@ -34,7 +34,7 @@ class Pagy
34
34
  'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.gap')}</a></li>),
35
35
  'after' => p_next ? %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li></ul>)
36
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])})
37
+ %(<nav id="#{id}" class="pagy-bootstrap-nav-js" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
38
38
  end
39
39
 
40
40
  # Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
@@ -48,7 +48,7 @@ class Pagy
48
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
49
  html << (p_next ? link.call(p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"')
50
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])})
51
+ html << %(</div></nav>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
52
52
  end
53
53
 
54
54
  end
@@ -38,7 +38,7 @@ class Pagy
38
38
  'active' => %(<li>#{link.call(PAGE_PLACEHOLDER, PAGE_PLACEHOLDER, %(class="pagination-link is-current" aria-current="page" aria-label="page #{PAGE_PLACEHOLDER}"))}</li>),
39
39
  'gap' => %(<li><span class="pagination-ellipsis">#{pagy_t('pagy.nav.gap')}</span></li>),
40
40
  'after' => '</ul>' }
41
- %(<nav id="#{id}" class="pagy-bulma-nav-js pagination is-centered" role="navigation" aria-label="pagination"></nav>#{pagy_json_tag(:nav, id, tags, pagy.sequels, defined?(TRIM) && pagy.vars[:page_param])})
41
+ %(<nav id="#{id}" class="pagy-bulma-nav-js pagination is-centered" role="navigation" aria-label="pagination"></nav>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
42
42
  end
43
43
 
44
44
  # Javascript combo pagination for Bulma: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
@@ -53,7 +53,7 @@ class Pagy
53
53
  html << %(<div class="pagy-combo-input control level is-mobile">#{pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)}</div>)
54
54
  html << (p_next ? %(<p class="control">#{link.call(p_next, pagy_t('pagy.nav.next'), 'class="button" aria-label="next page"')}</p>)
55
55
  : %(<p class="control"><a class="button" disabled>#{pagy_t('pagy.nav.next')}</a></p>))
56
- html << %(</div></nav>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
56
+ html << %(</div></nav>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
57
57
  end
58
58
 
59
59
  end
@@ -6,9 +6,6 @@ require 'pagy/countless'
6
6
 
7
7
  class Pagy
8
8
 
9
- # used by the items extra
10
- COUNTLESS = true
11
-
12
9
  module Backend ; private # the whole module is private so no problem with including it in a controller
13
10
 
14
11
  # Return Pagy object and items
@@ -2,12 +2,21 @@
2
2
  # encoding: utf-8
3
3
  # frozen_string_literal: true
4
4
 
5
- require 'pagy/extras/pagy_search'
6
-
7
5
  class Pagy
8
6
 
9
- # used by the items extra
10
- ELASTICSEARCH_RAILS = true
7
+ VARS[:elasticsearch_rails_search_method] ||= :pagy_search
8
+
9
+ module ElasticsearchRails
10
+ # returns an array used to delay the call of #search
11
+ # after the pagination variables are merged to the options
12
+ # it also pushes to the same array an eventually called method
13
+ def pagy_elasticsearch_rails(query_or_payload, **options)
14
+ [self, query_or_payload, options].tap do |args|
15
+ args.define_singleton_method(:method_missing){|*a| args += a}
16
+ end
17
+ end
18
+ alias_method VARS[:elasticsearch_rails_search_method], :pagy_elasticsearch_rails
19
+ end
11
20
 
12
21
  # create a Pagy object from an Elasticsearch::Model::Response::Response object
13
22
  def self.new_from_elasticsearch_rails(response, vars={})
@@ -23,16 +32,16 @@ class Pagy
23
32
 
24
33
  # Return Pagy object and items
25
34
  def pagy_elasticsearch_rails(pagy_search_args, vars={})
26
- model, search_args, _block, *called = pagy_search_args
27
- vars = pagy_elasticsearch_rails_get_vars(nil, vars)
28
- search_args[-1][:size] = vars[:items]
29
- search_args[-1][:from] = vars[:items] * (vars[:page] - 1)
30
- response = model.search(*search_args)
31
- total = response.respond_to?(:raw_response) ? response.raw_response['hits']['total'] : response.response['hits']['total']
32
- vars[:count] = total.is_a?(Hash) ? total['value'] : total
35
+ model, query_or_payload, options, *called = pagy_search_args
36
+ vars = pagy_elasticsearch_rails_get_vars(nil, vars)
37
+ options[:size] = vars[:items]
38
+ options[:from] = vars[:items] * (vars[:page] - 1)
39
+ response = model.search(query_or_payload, **options)
40
+ total = response.respond_to?(:raw_response) ? response.raw_response['hits']['total'] : response.response['hits']['total']
41
+ vars[:count] = total.is_a?(Hash) ? total['value'] : total
33
42
  pagy = Pagy.new(vars)
34
43
  # with :last_page overflow we need to re-run the method in order to get the hits
35
- if defined?(OVERFLOW) && pagy.overflow? && pagy.vars[:overflow] == :last_page
44
+ if defined?(Pagy::Overflow) && pagy.overflow? && pagy.vars[:overflow] == :last_page
36
45
  return pagy_elasticsearch_rails(pagy_search_args, vars.merge(page: pagy.page))
37
46
  end
38
47
  return pagy, called.empty? ? response : response.send(*called)
@@ -11,8 +11,8 @@ class Pagy
11
11
  def pagy_foundation_nav(pagy)
12
12
  link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
13
13
 
14
- html = EMPTY + (p_prev ? %(<li class="prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
15
- : %(<li class="prev disabled">#{pagy_t('pagy.nav.prev')}</li>))
14
+ html = +(p_prev ? %(<li class="prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
15
+ : %(<li class="prev disabled">#{pagy_t('pagy.nav.prev')}</li>))
16
16
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
17
17
  html << if item.is_a?(Integer); %(<li>#{link.call item}</li>) # page link
18
18
  elsif item.is_a?(String) ; %(<li class="current">#{item}</li>) # active page
@@ -36,7 +36,7 @@ class Pagy
36
36
  'after' => ( (p_next ? %(<li class="next">#{link.call(p_next, pagy_t('pagy.nav.next'), 'aria-label="next"')}</li>)
37
37
  : %(<li class="next disabled">#{pagy_t('pagy.nav.next')}</li>)) \
38
38
  + '</ul>' ) }
39
- %(<nav id="#{id}" class="pagy-foundation-nav-js" role="navigation" aria-label="Pagination"></nav>#{pagy_json_tag(:nav, id, tags, pagy.sequels, defined?(TRIM) && pagy.vars[:page_param])})
39
+ %(<nav id="#{id}" class="pagy-foundation-nav-js" role="navigation" aria-label="Pagination"></nav>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
40
40
  end
41
41
 
42
42
  # Javascript combo pagination for Foundation: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
@@ -50,7 +50,7 @@ class Pagy
50
50
  html << %(<span class="input-group-label">#{pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)}</span>)
51
51
  html << (p_next ? link.call(p_next, pagy_t('pagy.nav.next'), 'style="margin-bottom: 0px;" aria-label="next" class="next button primary"')
52
52
  : %(<a style="margin-bottom: 0px;" class="next button primary disabled" href="#">#{pagy_t('pagy.nav.next')}</a>))
53
- html << %(</div></nav>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
53
+ html << %(</div></nav>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
54
54
  end
55
55
 
56
56
  end
@@ -10,16 +10,10 @@ class Pagy
10
10
 
11
11
  Pagy::I18n.clear.instance_eval { undef :load; undef :t } # unload the pagy default constant for efficiency
12
12
 
13
- alias_method :pagy_without_i18n, :pagy_t
14
- if Gem::Version.new(::I18n::VERSION) < Gem::Version.new('1.6.0')
15
- def pagy_t_with_i18n(*args) ::I18n.t(*args) end
16
- else
17
- # keep 1.9 compatibility by hiding 2.0+ syntax in string
18
- module_eval <<-RUBY
19
- def pagy_t_with_i18n(key, **opts) ::I18n.t(key, **opts) end
20
- RUBY
13
+ module I18n
14
+ def pagy_t(key, **opts) = ::I18n.t(key, **opts)
21
15
  end
22
- alias_method :pagy_t, :pagy_t_with_i18n
16
+ prepend I18n
23
17
 
24
18
  end
25
19
  end
@@ -12,40 +12,32 @@ class Pagy
12
12
 
13
13
  ITEMS_PLACEHOLDER = '__pagy_items__'
14
14
 
15
- # Handle a custom number of :items from params
16
- module Backend ; private
17
-
18
- def pagy_with_items(vars)
19
- vars[:items] ||= (items = params[vars[:items_param] || VARS[:items_param]]) && # :items from :items_param
20
- [items.to_i, vars.key?(:max_items) ? vars[:max_items] : VARS[:max_items]].compact.min # :items capped to :max_items
21
- end
22
-
23
- # add the pagy*_get_vars alias-chained methods for frontend, and defined/required extras
24
- [nil, 'countless', 'elasticsearch_rails', 'searchkick'].each do |name|
25
- prefix, if_start, if_end = "_#{name}", "if defined?(Pagy::#{name.upcase})", "end" if name
26
- module_eval <<-RUBY
27
- #{if_start}
28
- alias_method :pagy#{prefix}_get_vars_without_items, :pagy#{prefix}_get_vars
29
- def pagy#{prefix}_get_vars_with_items(collection, vars)
30
- pagy_with_items(vars)
31
- pagy#{prefix}_get_vars_without_items(collection, vars)
32
- end
33
- alias_method :pagy#{prefix}_get_vars, :pagy#{prefix}_get_vars_with_items
34
- #{if_end}
35
- RUBY
15
+ module Items ; private
16
+
17
+ [:pagy_get_vars, :pagy_countless_get_vars, :pagy_elasticsearch_rails_get_vars, :pagy_searchkick_get_vars].each do |meth|
18
+ if Pagy::Backend.private_method_defined?(meth, true)
19
+ define_method(meth) do |collection, vars|
20
+ vars[:items] ||= (items = params[vars[:items_param] || VARS[:items_param]]) && # :items from :items_param
21
+ [items.to_i, vars.key?(:max_items) ? vars[:max_items] : VARS[:max_items]].compact.min # :items capped to :max_items
22
+ super(collection, vars)
23
+ end
24
+ end
36
25
  end
37
26
 
38
27
  end
28
+ Backend.prepend Items
29
+
39
30
 
40
31
  module Frontend
41
32
 
42
- alias_method :pagy_url_for_without_items, :pagy_url_for
43
- def pagy_url_for_with_items(page, pagy, url=false)
44
- p_vars = pagy.vars; params = request.GET.merge(p_vars[:params]); params[p_vars[:page_param].to_s] = page
45
- params[p_vars[:items_param].to_s] = p_vars[:items]
46
- "#{request.base_url if url}#{request.path}?#{Rack::Utils.build_nested_query(pagy_get_params(params))}#{p_vars[:anchor]}"
33
+ module Items
34
+ def pagy_url_for(page, pagy, url=false)
35
+ p_vars = pagy.vars; params = request.GET.merge(p_vars[:params]); params[p_vars[:page_param].to_s] = page
36
+ params[p_vars[:items_param].to_s] = p_vars[:items]
37
+ "#{request.base_url if url}#{request.path}?#{Rack::Utils.build_nested_query(pagy_get_params(params))}#{p_vars[:anchor]}"
38
+ end
47
39
  end
48
- alias_method :pagy_url_for, :pagy_url_for_with_items
40
+ prepend Items
49
41
 
50
42
  # Return the items selector HTML. For example "Show [20] items per page"
51
43
  def pagy_items_selector_js(pagy, id=pagy_id)
@@ -55,10 +47,10 @@ class Pagy
55
47
  link = pagy_marked_link(pagy_link_proc(pagy))
56
48
  p_vars[:items] = p_items # restore the items
57
49
 
58
- html = EMPTY + %(<span id="#{id}">)
50
+ html = %(<span id="#{id}">)
59
51
  input = %(<input type="number" min="1" max="#{p_vars[:max_items]}" value="#{p_items}" style="padding: 0; text-align: center; width: #{p_items.to_s.length+1}rem;">)
60
52
  html << %(#{pagy_t('pagy.items_selector_js', item_name: pagy_t(p_vars[:i18n_key], count: p_items), items_input: input, count: p_items)})
61
- html << %(</span>#{pagy_json_tag(:items_selector, id, pagy.from, link, defined?(TRIM) && p_vars[:page_param])})
53
+ html << %(</span>#{pagy_json_tag(pagy, :items_selector, id, pagy.from, link)})
62
54
  end
63
55
 
64
56
  end
@@ -10,8 +10,8 @@ class Pagy
10
10
  # Pagination for materialize: it returns the html with the series of links to the pages
11
11
  def pagy_materialize_nav(pagy)
12
12
  link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
13
- html = EMPTY + (p_prev ? %(<li class="waves-effect prev">#{link.call p_prev, '<i class="material-icons">chevron_left</i>', 'aria-label="previous"'}</li>)
14
- : %(<li class="prev disabled"><a href="#"><i class="material-icons">chevron_left</i></a></li>))
13
+ html = (p_prev ? %(<li class="waves-effect prev">#{link.call p_prev, '<i class="material-icons">chevron_left</i>', 'aria-label="previous"'}</li>)
14
+ : +%(<li class="prev disabled"><a href="#"><i class="material-icons">chevron_left</i></a></li>))
15
15
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
16
16
  html << if item.is_a?(Integer); %(<li class="waves-effect">#{link.call item}</li>) # page link
17
17
  elsif item.is_a?(String) ; %(<li class="active">#{link.call item}</li>) # active page
@@ -35,7 +35,7 @@ class Pagy
35
35
  'after' => ( (p_next ? %(<li class="waves-effect next">#{link.call(p_next, '<i class="material-icons">chevron_right</i>', 'aria-label="next"')}</li>)
36
36
  : %(<li class="next disabled"><a href="#"><i class="material-icons">chevron_right</i></a></li>)) \
37
37
  + '</ul>' ) }
38
- %(<div id="#{id}" class="pagy-materialize-nav-js" role="navigation" aria-label="pager"></div>#{pagy_json_tag(:nav, id, tags, pagy.sequels, defined?(TRIM) && pagy.vars[:page_param])})
38
+ %(<div id="#{id}" class="pagy-materialize-nav-js" role="navigation" aria-label="pager"></div>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
39
39
  end
40
40
 
41
41
  # Javascript combo pagination for materialize: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
@@ -52,7 +52,7 @@ class Pagy
52
52
  html << %(<div class="pagy-combo-input btn-flat" style="cursor: default; padding: 0px">#{pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)}</div>)
53
53
  html << (p_next ? %(<li class="waves-effect next" #{li_style}>#{link.call p_next, '<i class="material-icons">chevron_right</i>', 'aria-label="next"'}</li>)
54
54
  : %(<li class="next disabled" #{li_style}><a href="#"><i class="material-icons">chevron_right</i></a></li>))
55
- html << %(</ul></div>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
55
+ html << %(</ul></div>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
56
56
  end
57
57
 
58
58
  end
@@ -17,21 +17,21 @@ class Pagy
17
17
  'gap' => %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> ),
18
18
  'after' => p_next ? %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
19
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(:nav, id, tags, pagy.sequels, defined?(TRIM) && pagy.vars[:page_param])})
20
+ %(<nav id="#{id}" class="pagy-nav-js pagination" role="navigation" aria-label="pager"></nav>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
21
21
  end
22
22
 
23
23
  # Javascript combo pagination: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
24
24
  def pagy_combo_nav_js(pagy, id=pagy_id)
25
25
  link, p_prev, p_next, p_page, p_pages = pagy_link_proc(pagy), pagy.prev, pagy.next, pagy.page, pagy.pages
26
26
 
27
- html = EMPTY + %(<nav id="#{id}" class="pagy-combo-nav-js pagination" role="navigation" aria-label="pager">)
27
+ html = %(<nav id="#{id}" class="pagy-combo-nav-js pagination" role="navigation" aria-label="pager">)
28
28
  html << (p_prev ? %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
29
29
  : %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> ))
30
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
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
32
  html << (p_next ? %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
33
33
  : %(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>))
34
- html << %(</nav>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
34
+ html << %(</nav>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
35
35
  end
36
36
 
37
37
  end
@@ -4,68 +4,71 @@
4
4
 
5
5
  class Pagy
6
6
 
7
- OVERFLOW = true
7
+ module Overflow
8
+ VARS[:overflow] = :empty_page
8
9
 
9
- VARS[:overflow] = :empty_page
10
+ def overflow? = @overflow
10
11
 
11
- def overflow?; @overflow end
12
-
13
- alias_method :initialize_without_overflow, :initialize
14
- def initialize_with_overflow(vars)
15
- @overflow ||= false # don't override if :last_page re-run the method after an overflow
16
- initialize_without_overflow(vars)
17
- rescue OverflowError
18
- @overflow = true # add the overflow flag
19
- case @vars[:overflow]
20
- when :exception
21
- raise # same as without the extra
22
- when :last_page
23
- initial_page = @vars[:page] # save the very initial page (even after re-run)
24
- initialize(vars.merge!(page: @last)) # re-run with the last page
25
- @vars[:page] = initial_page # restore the inital page
26
- when :empty_page
27
- @offset = @items = @from = @to = 0 # vars relative to the actual page
28
- @prev = @last # prev relative to the actual page
29
- extend(Series) # special series for :empty_page
30
- else
31
- raise VariableError.new(self), "expected :overflow variable in [:last_page, :empty_page, :exception]; got #{@vars[:overflow].inspect}"
12
+ def initialize(vars)
13
+ @overflow ||= false # don't override if :last_page re-run the method after an overflow
14
+ super
15
+ rescue OverflowError
16
+ @overflow = true # add the overflow flag
17
+ case @vars[:overflow]
18
+ when :exception
19
+ raise # same as without the extra
20
+ when :last_page
21
+ 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
23
+ @vars[:page] = initial_page # restore the inital page
24
+ when :empty_page
25
+ @offset = @items = @from = @to = 0 # vars relative to the actual page
26
+ @prev = @last # prev relative to the actual page
27
+ extend(Series) # special series for :empty_page
28
+ else
29
+ raise VariableError.new(self), "expected :overflow variable in [:last_page, :empty_page, :exception]; got #{@vars[:overflow].inspect}"
30
+ end
32
31
  end
33
- end
34
- alias_method :initialize, :initialize_with_overflow
35
32
 
36
- module Series
37
- def series(size=@vars[:size])
38
- @page = @last # series for last page
39
- super(size).tap do |s| # call original series
33
+ module Series
34
+ def series(size=@vars[:size])
35
+ @page = @last # series for last page
36
+ super(size).tap do |s| # call original series
40
37
  s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
41
38
  @page = @vars[:page] # restore the actual page
39
+ end
42
40
  end
43
41
  end
42
+
44
43
  end
44
+ prepend Overflow
45
45
 
46
46
 
47
47
  # support for Pagy::Countless
48
48
  if defined?(Pagy::Countless)
49
49
  class Countless
50
50
 
51
- alias_method :finalize_without_overflow, :finalize
52
- def finalize_with_overflow(items)
53
- @overflow = false
54
- finalize_without_overflow(items)
55
- rescue OverflowError
56
- @overflow = true # add the overflow flag
57
- case @vars[:overflow]
58
- when :exception
59
- raise # same as without the extra
60
- when :empty_page
61
- @offset = @items = @from = @to = 0 # vars relative to the actual page
62
- @vars[:size] = [] # no page in the series
63
- self
64
- else
65
- raise VariableError.new(self), "expected :overflow variable in [:empty_page, :exception]; got #{@vars[:overflow].inspect}"
51
+ module Overflow
52
+
53
+ def finalize(items)
54
+ @overflow = false
55
+ super
56
+ rescue OverflowError
57
+ @overflow = true # add the overflow flag
58
+ case @vars[:overflow]
59
+ when :exception
60
+ raise # same as without the extra
61
+ when :empty_page
62
+ @offset = @items = @from = @to = 0 # vars relative to the actual page
63
+ @vars[:size] = [] # no page in the series
64
+ self
65
+ else
66
+ raise VariableError.new(self), "expected :overflow variable in [:empty_page, :exception]; got #{@vars[:overflow].inspect}"
67
+ end
66
68
  end
69
+
67
70
  end
68
- alias_method :finalize, :finalize_with_overflow
71
+ prepend Overflow
69
72
 
70
73
  end
71
74
  end
@@ -2,12 +2,21 @@
2
2
  # encoding: utf-8
3
3
  # frozen_string_literal: true
4
4
 
5
- require 'pagy/extras/pagy_search'
6
-
7
5
  class Pagy
8
6
 
9
- # used by the items extra
10
- SEARCHKICK = true
7
+ VARS[:searchkick_search_method] ||= :pagy_search
8
+
9
+ module Searchkick
10
+ # returns an array used to delay the call of #search
11
+ # after the pagination variables are merged to the options
12
+ # it also pushes to the same array an eventually called method
13
+ def pagy_searchkick(term = "*", **options, &block)
14
+ [self, term, options, block].tap do |args|
15
+ args.define_singleton_method(:method_missing){|*a| args += a}
16
+ end
17
+ end
18
+ alias_method VARS[:searchkick_search_method], :pagy_searchkick
19
+ end
11
20
 
12
21
  # create a Pagy object from a Searchkick::Results object
13
22
  def self.new_from_searchkick(results, vars={})
@@ -22,15 +31,15 @@ class Pagy
22
31
 
23
32
  # Return Pagy object and results
24
33
  def pagy_searchkick(pagy_search_args, vars={})
25
- model, search_args, block, *called = pagy_search_args
26
- vars = pagy_searchkick_get_vars(nil, vars)
27
- search_args[-1][:per_page] = vars[:items]
28
- search_args[-1][:page] = vars[:page]
29
- results = model.search(*search_args, &block)
30
- vars[:count] = results.total_count
34
+ model, term, options, block, *called = pagy_search_args
35
+ vars = pagy_searchkick_get_vars(nil, vars)
36
+ options[:per_page] = vars[:items]
37
+ options[:page] = vars[:page]
38
+ results = model.search(term, **options, &block)
39
+ vars[:count] = results.total_count
31
40
  pagy = Pagy.new(vars)
32
41
  # with :last_page overflow we need to re-run the method in order to get the hits
33
- if defined?(OVERFLOW) && pagy.overflow? && pagy.vars[:overflow] == :last_page
42
+ if defined?(Pagy::Overflow) && pagy.overflow? && pagy.vars[:overflow] == :last_page
34
43
  return pagy_searchkick(pagy_search_args, vars.merge(page: pagy.page))
35
44
  end
36
45
  return pagy, called.empty? ? results : results.send(*called)
@@ -11,8 +11,8 @@ class Pagy
11
11
  def pagy_semantic_nav(pagy)
12
12
  link, p_prev, p_next = pagy_link_proc(pagy, 'class="item"'), pagy.prev, pagy.next
13
13
 
14
- html = EMPTY + (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 = (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>))
16
16
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
17
17
  html << if item.is_a?(Integer); %(#{link.call item}) # page link
18
18
  elsif item.is_a?(String) ; %(<a class="item active">#{item}</a>) # current page
@@ -34,21 +34,21 @@ class Pagy
34
34
  'gap' => %(<div class="disabled item">#{pagy_t('pagy.nav.gap')}</div>),
35
35
  'after' => (p_next ? %(#{link.call(p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"')})
36
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(:nav, id, tags, pagy.sequels, defined?(TRIM) && pagy.vars[:page_param])})
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)})
38
38
  end
39
39
 
40
40
  # Combo pagination for semantic: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
41
41
  def pagy_semantic_combo_nav_js(pagy, id=pagy_id)
42
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
43
 
44
- html = EMPTY + %(<div id="#{id}" class="pagy-semantic-combo-nav-js ui compact menu" role="navigation" aria-label="pager">)
44
+ html = %(<div id="#{id}" class="pagy-semantic-combo-nav-js ui compact menu" role="navigation" aria-label="pager">)
45
45
  html << (p_prev ? %(#{link.call p_prev, '<i class="left small chevron icon"></i>', 'aria-label="previous"'})
46
46
  : %(<div class="item disabled"><i class="left small chevron icon"></i></div>))
47
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
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
49
  html << (p_next ? %(#{link.call p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"'})
50
50
  : %(<div class="item disabled"><i class="right small chevron icon"></i></div>))
51
- html << %(</div>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
51
+ html << %(</div>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
52
52
  end
53
53
 
54
54
  end
@@ -27,26 +27,24 @@ class Pagy
27
27
 
28
28
  if defined?(Oj)
29
29
  # it returns a script tag with the JSON-serialized args generated with the faster oj gem
30
- def pagy_json_tag(*args)
30
+ def pagy_json_tag(pagy, *args)
31
+ args << ( defined?(Trim) && pagy.vars[:page_param] )
31
32
  %(<script type="application/json" class="pagy-json">#{Oj.dump(args, mode: :strict)}</script>)
32
33
  end
33
34
  else
34
35
  require 'json'
35
36
  # it returns a script tag with the JSON-serialized args generated with the slower to_json
36
- def pagy_json_tag(*args)
37
+ def pagy_json_tag(pagy, *args)
38
+ args << ( defined?(Trim) && pagy.vars[:page_param] )
37
39
  %(<script type="application/json" class="pagy-json">#{args.to_json}</script>)
38
40
  end
39
41
  end
40
42
 
41
43
  # it returns the SHA1 (fastest on modern ruby) string used as default `id` attribute by all the `*_js` tags
42
- def pagy_id
43
- "pagy-#{Digest::SHA1.hexdigest(caller(2..2)[0].split(':in')[0])}"
44
- end
44
+ def pagy_id = "pagy-#{Digest::SHA1.hexdigest(caller(2..2)[0].split(':in')[0])}"
45
45
 
46
46
  # it returns the marked link to used by pagy.js
47
- def pagy_marked_link(link)
48
- link.call(PAGE_PLACEHOLDER, '', 'style="display: none;"')
49
- end
47
+ def pagy_marked_link(link) = link.call(PAGE_PLACEHOLDER, '', 'style="display: none;"')
50
48
 
51
49
  end
52
50
 
@@ -4,20 +4,16 @@
4
4
 
5
5
  class Pagy
6
6
 
7
- module Frontend
8
-
9
- TRIM = true # boolean used by *_js helpers
10
-
11
- alias_method :pagy_link_proc_without_trim, :pagy_link_proc
12
- def pagy_link_proc_with_trim(pagy, link_extra='')
13
- link_proc = pagy_link_proc_without_trim(pagy, link_extra)
7
+ module Trim
8
+ def pagy_link_proc(pagy, link_extra='')
9
+ link_proc = super(pagy, link_extra)
14
10
  re = /[?&]#{pagy.vars[:page_param]}=1\b(?!&)|\b#{pagy.vars[:page_param]}=1&/
15
11
  lambda do |n, text=n, extra=''|
16
12
  link = link_proc.call(n, text, extra)
17
13
  n == 1 ? link.sub(re, '') : link
18
14
  end
19
15
  end
20
- alias_method :pagy_link_proc, :pagy_link_proc_with_trim
21
-
22
16
  end
17
+ Frontend.prepend Trim
18
+
23
19
  end
@@ -12,8 +12,8 @@ class Pagy
12
12
  link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
13
13
 
14
14
  previous_span = "<span uk-pagination-previous>#{pagy_t('pagy.nav.prev')}</span>"
15
- html = EMPTY + (p_prev ? %(<li>#{link.call p_prev, previous_span}</li>)
16
- : %(<li class="uk-disabled"><a href="#">#{previous_span}</a></li>))
15
+ html = (p_prev ? %(<li>#{link.call p_prev, previous_span}</li>)
16
+ : %(<li class="uk-disabled"><a href="#">#{previous_span}</a></li>))
17
17
  pagy.series.each do |item|
18
18
  html << if item.is_a?(Integer); %(<li>#{link.call item}</li>)
19
19
  elsif item.is_a?(String) ; %(<li class="uk-active"><span>#{item}</span></li>)
@@ -38,7 +38,7 @@ class Pagy
38
38
  'gap' => %(<li class="uk-disabled"><span>#{pagy_t('pagy.nav.gap')}</span></li>),
39
39
  'after' => p_next ? %(<li>#{link.call p_next, next_span}</li>)
40
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(:nav, id, tags, pagy.sequels, defined?(TRIM) && pagy.vars[:page_param])})
41
+ %(<ul id="#{id}" class="pagy-uikit-nav-js uk-pagination uk-flex-center"></ul>#{pagy_json_tag(pagy, :nav, id, tags, pagy.sequels)})
42
42
  end
43
43
 
44
44
  # Javascript combo pagination for uikit: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
@@ -56,7 +56,7 @@ class Pagy
56
56
  html << (p_next ? link.call(p_next, pagy_t('pagy.nav.next'), 'class="uk-button uk-button-default"')
57
57
  : %(<button class="uk-button uk-button-default" disabled>#{pagy_t('pagy.nav.next')}</button>))
58
58
 
59
- html << %(</div>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
59
+ html << %(</div>#{pagy_json_tag(pagy, :combo_nav, id, p_page, pagy_marked_link(link))})
60
60
  end
61
61
  end
62
62
  end
data/lib/pagy/frontend.rb CHANGED
@@ -29,15 +29,12 @@ class Pagy
29
29
 
30
30
  include Helpers
31
31
 
32
- EMPTY = '' # EMPTY + 'string' is almost as fast as +'string' but is also 1.9 compatible
33
- MARK = PAGE_PLACEHOLDER # backward compatibility in case of helper-overriding in legacy apps
34
-
35
32
  # Generic pagination: it returns the html with the series of links to the pages
36
33
  def pagy_nav(pagy)
37
34
  link, p_prev, p_next = pagy_link_proc(pagy), pagy.prev, pagy.next
38
35
 
39
- html = EMPTY + (p_prev ? %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
40
- : %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> ))
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> ))
41
38
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
42
39
  html << if item.is_a?(Integer); %(<span class="page">#{link.call item}</span> ) # page link
43
40
  elsif item.is_a?(String) ; %(<span class="page active">#{item}</span> ) # current page
@@ -51,10 +48,10 @@ class Pagy
51
48
 
52
49
  # Return examples: "Displaying items 41-60 of 324 in total" of "Displaying Products 41-60 of 324 in total"
53
50
  def pagy_info(pagy, item_name=nil)
54
- path = if (count = pagy.count) == 0 ; 'pagy.info.no_items'
51
+ key = if (count = pagy.count) == 0 ; 'pagy.info.no_items'
55
52
  else pagy.pages == 1 ? 'pagy.info.single_page' : 'pagy.info.multiple_pages'
56
53
  end
57
- pagy_t(path, item_name: item_name || pagy_t(pagy.vars[:i18n_key], count: count), count: count, from: pagy.from, to: pagy.to)
54
+ pagy_t(key, item_name: item_name || pagy_t(pagy.vars[:i18n_key], count: count), count: count, from: pagy.from, to: pagy.to)
58
55
  end
59
56
 
60
57
  # Returns a performance optimized proc to generate the HTML links
@@ -69,7 +66,7 @@ class Pagy
69
66
 
70
67
  # Similar to I18n.t: just ~18x faster using ~10x less memory
71
68
  # (@pagy_locale explicitly initilized in order to avoid warning)
72
- def pagy_t(path, vars={}) Pagy::I18n.t(@pagy_locale||=nil, path, vars) end
69
+ def pagy_t(key, **opts) = Pagy::I18n.t(@pagy_locale||=nil, key, **opts)
73
70
 
74
71
  end
75
72
  end
data/pagy.gemspec ADDED
@@ -0,0 +1,16 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'pagy'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'pagy'
7
+ s.version = Pagy::VERSION
8
+ s.authors = ['Domizio Demichelis']
9
+ s.email = ['dd.nexus@gmail.com']
10
+ s.summary = 'The Ultimate Pagination Ruby Gem'
11
+ s.description = 'Agnostic pagination in plain ruby: it works with any framework, ORM and DB type, with all kinds of collections, even pre-paginated, scopes, Arrays, JSON data... Easy, powerful, fast and light.'
12
+ s.homepage = 'https://github.com/ddnexus/pagy'
13
+ s.license = 'MIT'
14
+ s.files = `git ls-files -z`.split("\x0").select{|f| f.start_with?('lib', 'pagy.gemspec', 'LICENSE') }
15
+ s.required_ruby_version = '>= 3.0'
16
+ 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: 3.14.0
4
+ version: 4.0.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-06-10 00:00:00.000000000 Z
11
+ date: 2021-03-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,
@@ -22,8 +22,8 @@ files:
22
22
  - LICENSE.txt
23
23
  - lib/config/pagy.rb
24
24
  - lib/javascripts/pagy.js
25
+ - lib/locales/README.md
25
26
  - lib/locales/bg.yml
26
- - lib/locales/bs.yml
27
27
  - lib/locales/ca.yml
28
28
  - lib/locales/cs.yml
29
29
  - lib/locales/da.yml
@@ -31,7 +31,6 @@ files:
31
31
  - lib/locales/en.yml
32
32
  - lib/locales/es.yml
33
33
  - lib/locales/fr.yml
34
- - lib/locales/hr.yml
35
34
  - lib/locales/id.yml
36
35
  - lib/locales/it.yml
37
36
  - lib/locales/ja.yml
@@ -43,7 +42,6 @@ files:
43
42
  - lib/locales/pt-BR.yml
44
43
  - lib/locales/pt.yml
45
44
  - lib/locales/ru.yml
46
- - lib/locales/sr.yml
47
45
  - lib/locales/sv-SE.yml
48
46
  - lib/locales/sv.yml
49
47
  - lib/locales/sw.yml
@@ -72,7 +70,6 @@ files:
72
70
  - lib/pagy/extras/metadata.rb
73
71
  - lib/pagy/extras/navs.rb
74
72
  - lib/pagy/extras/overflow.rb
75
- - lib/pagy/extras/pagy_search.rb
76
73
  - lib/pagy/extras/searchkick.rb
77
74
  - lib/pagy/extras/semantic.rb
78
75
  - lib/pagy/extras/shared.rb
@@ -95,29 +92,18 @@ files:
95
92
  - lib/templates/uikit_nav.html.erb
96
93
  - lib/templates/uikit_nav.html.haml
97
94
  - lib/templates/uikit_nav.html.slim
95
+ - pagy.gemspec
98
96
  homepage: https://github.com/ddnexus/pagy
99
97
  licenses:
100
98
  - MIT
101
99
  metadata: {}
102
- post_install_message: |2+
103
-
104
- IMPORTANT: Pagy 4.8+ has been backported and supports ruby 2.5+ now!
105
-
106
- If you run on ruby 2.5+, upgrading requires no change in the code
107
- unless you are using the searchkick or the elasticsearch_rails extras
108
- (and in that case it requires just a single rename).
109
-
110
- See https://github.com/ddnexus/pagy for details.
111
-
100
+ post_install_message:
112
101
  rdoc_options: []
113
102
  require_paths:
114
103
  - lib
115
104
  required_ruby_version: !ruby/object:Gem::Requirement
116
105
  requirements:
117
106
  - - ">="
118
- - !ruby/object:Gem::Version
119
- version: '1.9'
120
- - - "<"
121
107
  - !ruby/object:Gem::Version
122
108
  version: '3.0'
123
109
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -126,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
112
  - !ruby/object:Gem::Version
127
113
  version: '0'
128
114
  requirements: []
129
- rubygems_version: 3.1.6
115
+ rubygems_version: 3.2.3
130
116
  signing_key:
131
117
  specification_version: 4
132
118
  summary: The Ultimate Pagination Ruby Gem
data/lib/locales/bs.yml DELETED
@@ -1,24 +0,0 @@
1
- # :east_slavic pluralization (see https://github.com/ddnexus/pagy/blob/master/lib/locales/utils/p11n.rb)
2
-
3
- bs:
4
- pagy:
5
-
6
- item_name:
7
- one: "stavka"
8
- few: "stavke"
9
- many: "stavki"
10
- other: "stavki"
11
-
12
- nav:
13
- prev: "&lsaquo;&nbsp;Prethodna"
14
- next: "Sljedeća &nbsp;&rsaquo;"
15
- gap: "&hellip;"
16
-
17
- info:
18
- no_items: "Nije pronađena %{item_name}"
19
- single_page: "Prikazuje se <b>%{count}</b> %{item_name}"
20
- multiple_pages: "Prikaz %{item_name} <b>%{from}-%{to}</b> od <b>%{count}</b> ukupno"
21
-
22
- combo_nav_js: "Stranica %{page_input} od %{pages}"
23
-
24
- items_selector_js: "Prikaži %{items_input} %{item_name} po stranici"
data/lib/locales/hr.yml DELETED
@@ -1,24 +0,0 @@
1
- # :east_slavic pluralization (see https://github.com/ddnexus/pagy/blob/master/lib/locales/utils/p11n.rb)
2
-
3
- hr:
4
- pagy:
5
-
6
- item_name:
7
- one: "stavka"
8
- few: "stavke"
9
- many: "stavki"
10
- other: "stavki"
11
-
12
- nav:
13
- prev: "&lsaquo;&nbsp;Prethodna"
14
- next: "Sljedeća &nbsp;&rsaquo;"
15
- gap: "&hellip;"
16
-
17
- info:
18
- no_items: "Nije pronađena %{item_name}"
19
- single_page: "Prikazuje se <b>%{count}</b> %{item_name}"
20
- multiple_pages: "Prikaz %{item_name} <b>%{from}-%{to}</b> od <b>%{count}</b> ukupno"
21
-
22
- combo_nav_js: "Stranica %{page_input} od %{pages}"
23
-
24
- items_selector_js: "Prikaži %{items_input} %{item_name} po stranici"
data/lib/locales/sr.yml DELETED
@@ -1,23 +0,0 @@
1
- # :east_slavic pluralization (see https://github.com/ddnexus/pagy/blob/master/lib/locales/utils/p11n.rb)
2
-
3
- sr:
4
- pagy:
5
- item_name:
6
- one: "ставка"
7
- few: "ставкe"
8
- many: "ставки"
9
- other: "ставки"
10
-
11
- nav:
12
- prev: "&lsaquo;&nbsp;Претходна"
13
- next: "Следећa &nbsp;&rsaquo;"
14
- gap: "&hellip;"
15
-
16
- info:
17
- no_items: "Нema пронађених %{item_name}"
18
- single_page: "Приказује се <b>%{count}</b> %{item_name}"
19
- multiple_pages: "Приказ %{item_name} <b>%{from}-%{to}</b> од <b>%{count}</b> укупно"
20
-
21
- combo_nav_js: "Страниca %{page_input} од %{pages}"
22
-
23
- items_selector_js: "Прикажи %{items_input} %{item_name} по страниcи"
@@ -1,18 +0,0 @@
1
- # Support module to capture search calls
2
- # encoding: utf-8
3
- # frozen_string_literal: true
4
-
5
- class Pagy
6
- module Search
7
- # returns an array used to delay the call of #search
8
- # after the pagination variables are merged to the options
9
- # it also pushes to the same array an eventually called method and arguments
10
- # the last search argument must be a hash option
11
- def pagy_search(*search_args, &block)
12
- search_args << {} unless search_args[-1].is_a?(Hash)
13
- [self, search_args, block].tap do |args|
14
- args.define_singleton_method(:method_missing){|*a| args += a}
15
- end
16
- end
17
- end
18
- end