pagy 0.8.6 → 0.9.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: 8e60b4173be015ffca66290f5a3cf17ac3a310300384661aa5e2fa247ce58f68
4
- data.tar.gz: 358cdc2134cc73f7f289de33cb02c821158797ee8dd21e88e05cf690085e0143
3
+ metadata.gz: 8867ae39673157a4e3256e40bb71a435d4bc45418ece6c510ac4913fc8d2c917
4
+ data.tar.gz: f5cd6d9d8becbdd00c9878f4c10472302e2813b3163fe33bc21bd71c240544e3
5
5
  SHA512:
6
- metadata.gz: c7b4d97d281802fe983e2a748524cad6971bf9df58baa0cf34f1e35a0647ace2644b50b56e76727b2fe231043ed8a34cbc84bf206350596e81fe95c15b3a6e2f
7
- data.tar.gz: '083afad91cdb22b2a6e036c25c5fca9cfe147747c3a348b86a9d471c165417f06a3622b88e3b25160fe893b25e533ac2c468434744d1e0f0f677ee274df87ff7'
6
+ metadata.gz: 27619900377812a56104aa89542ebe6b6ab2201231b725ca1e708b3b02e0f540265d525e2bbe9647fa993338e6fe0003a0380818daaabc7405671910215fa064
7
+ data.tar.gz: 726345048bbd3056b6612d4acbe11bdf76e6abb515b3948cf165668da05dc99071d2086ec235466281be1543b344f81de4f6422941db883d537534b9369499ac
@@ -17,5 +17,8 @@ en:
17
17
  one: "item"
18
18
  other: "items"
19
19
  compact:
20
- page: Page
21
- of: of
20
+ page: "Page"
21
+ of: "of"
22
+ items:
23
+ show: "Show"
24
+ items: "items per page"
@@ -2,11 +2,11 @@
2
2
 
3
3
  require 'pathname'
4
4
 
5
- class Pagy ; VERSION = '0.8.6'
5
+ class Pagy ; VERSION = '0.9.0'
6
6
 
7
7
  class OutOfRangeError < StandardError; end
8
8
 
9
- # root pathname to get the path of pagy files like templates or dictionaries
9
+ # Root pathname to get the path of Pagy files like templates or dictionaries
10
10
  def self.root; Pathname.new(__FILE__).dirname end
11
11
 
12
12
  # default vars
@@ -14,11 +14,11 @@ class Pagy ; VERSION = '0.8.6'
14
14
 
15
15
  attr_reader :count, :page, :items, :vars, :pages, :last, :offset, :from, :to, :prev, :next
16
16
 
17
- # merge and validate the options, do some simple aritmetic and set the instance variables
17
+ # Merge and validate the options, do some simple aritmetic and set the instance variables
18
18
  def initialize(vars)
19
- @vars = VARS.merge(vars.delete_if{|_,v| v.nil? || v == ''.freeze }) # default vars + cleaned instance vars
20
- { count:0, items:1, outset:0, page:1 }.each do |k,min| # validate core variables
21
- (@vars[k] && instance_variable_set(:"@#{k}", @vars.delete(k).to_i) >= min) \
19
+ @vars = VARS.merge(vars.delete_if{|_,v| v.nil? || v == ''.freeze }) # 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
22
  or raise(ArgumentError, "expected :#{k} >= #{min}; got #{instance_variable_get(:"@#{k}").inspect}")
23
23
  end
24
24
  @pages = @last = [(@count.to_f / @items).ceil, 1].max # cardinal and ordinal meanings
@@ -31,7 +31,7 @@ class Pagy ; VERSION = '0.8.6'
31
31
  @next = (@page+1 unless @page == @last) # nil if no next page
32
32
  end
33
33
 
34
- # return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
34
+ # Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
35
35
  def series(size=@vars[:size])
36
36
  4.times{|i| (size[i]>=0 rescue nil) or raise(ArgumentError, "expected 4 items >= 0 in :size; got #{size.inspect}")}
37
37
  series = []
@@ -1,30 +1,29 @@
1
1
  # See Pagy::Backend API documentation: https://ddnexus.github.io/pagy/api/backend
2
2
 
3
3
  class Pagy
4
- # Defines a few generic methods to paginate a ORM collection out of the box,
5
- # or any collection by overriding pagy_get_items in your controller
4
+ # Defines a few generic methods to paginate an ORM collection out of the box,
5
+ # or any collection by overriding pagy_get_items and/or pagy_get_vars in your controller
6
6
 
7
- # See also the extras if you need specialized methods to paginate
8
- # Arrays, ORM, and other TBD collections
7
+ # See also the extras if you need specialized methods to paginate Arrays or other collections
9
8
 
10
9
  module Backend ; private # the whole module is private so no problem with including it in a controller
11
10
 
12
- # return pagy object and items
11
+ # Return Pagy object and items
13
12
  def pagy(collection, vars={})
14
13
  pagy = Pagy.new(pagy_get_vars(collection, vars))
15
14
  return pagy, pagy_get_items(collection, pagy)
16
15
  end
17
16
 
18
- # sub-method called only by #pagy: here for easy customization of variables by overriding
17
+ # Sub-method called only by #pagy: here for easy customization of variables by overriding
19
18
  def pagy_get_vars(collection, vars)
20
- # return the merged variables to initialize the pagy object
21
- { count: collection.count(:all),
19
+ # Return the merged variables to initialize the Pagy object
20
+ { count: collection.count(:all), # works with AR, but may not work with other ORMs
22
21
  page: params[vars[:page_param]||VARS[:page_param]] }.merge!(vars)
23
22
  end
24
23
 
25
- # sub-method called only by #pagy: here for easy customization of record-extraction by overriding
24
+ # Sub-method called only by #pagy: here for easy customization of record-extraction by overriding
26
25
  def pagy_get_items(collection, pagy)
27
- # this should work with ActiveRecord, Sequel, Mongoid...
26
+ # This should work with ActiveRecord, Sequel, Mongoid...
28
27
  collection.offset(pagy.offset).limit(pagy.items)
29
28
  end
30
29
 
@@ -1,17 +1,17 @@
1
- # See the Pagy Extras documentation: https://ddnexus.github.io/pagy/extras
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/array
2
2
 
3
3
  class Pagy
4
4
  # Add specialized backend methods to paginate array collections
5
5
  module Backend ; private
6
6
 
7
- # return pagy object and items
7
+ # Return Pagy object and items
8
8
  def pagy_array(array, vars={})
9
9
  pagy = Pagy.new(pagy_array_get_vars(array, vars))
10
10
  return pagy, array[pagy.offset, pagy.items]
11
11
  end
12
12
 
13
13
  def pagy_array_get_vars(array, vars)
14
- # return the merged variables to initialize the pagy object
14
+ # Return the merged variables to initialize the Pagy object
15
15
  { count: array.count,
16
16
  page: params[vars[:page_param]||VARS[:page_param]] }.merge!(vars)
17
17
  end
@@ -1,4 +1,4 @@
1
- # See the Pagy Extras documentation: https://ddnexus.github.io/pagy/extras
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bootstrap
2
2
 
3
3
  class Pagy
4
4
  # Add nav helper for bootstrap pagination
@@ -1,4 +1,4 @@
1
- # See the Pagy Extras documentation: https://ddnexus.github.io/pagy/extras
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/compact
2
2
 
3
3
  class Pagy
4
4
  # Add nav helpers for compact pagination
@@ -1,4 +1,4 @@
1
- # See the Pagy Extras documentation: https://ddnexus.github.io/pagy/extras
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/i18n
2
2
 
3
3
  class Pagy
4
4
  # Use ::I18n gem
@@ -6,7 +6,7 @@ class Pagy
6
6
 
7
7
  ::I18n.load_path << Pagy.root.join('locales', 'pagy.yml')
8
8
 
9
- # overrides the built-in pagy_t
9
+ # Override the built-in pagy_t
10
10
  def pagy_t(*args)
11
11
  I18n.t(*args)
12
12
  end
@@ -17,23 +17,31 @@
17
17
  # See https://ddnexus.github.io/pagy/extras/compact
18
18
  # require 'pagy/extras/compact'
19
19
 
20
- # I18n: Uses the `I18n` gem instead of the pagy implementation
20
+ # I18n: Use the `I18n` gem instead of the pagy implementation
21
21
  # See https://ddnexus.github.io/pagy/extras/i18n
22
22
  # require 'pagy/extras/i18n'
23
23
 
24
+ # Items: Handle the page :items passed with the params
25
+ # See https://ddnexus.github.io/pagy/extras/items
26
+ # require 'pagy/extras/items'
27
+ # Pagy::VARS[:items_param] = :items # default
28
+ # Pagy::VARS[:max_items] = 100 # default
29
+
24
30
  # Responsive: On resize, the number of page links will adapt in real-time to the available window or container width
25
31
  # See https://ddnexus.github.io/pagy/extras/responsive
26
32
  # require 'pagy/extras/responsive'
33
+ # See https://ddnexus.github.io/pagy/extras/responsive#breakpoints
34
+ # Pagy::VARS[:breakpoints] = { 0 => [1,2,2,1], 350 => [2,3,3,2], 550 => [3,4,4,3] } # example of width/size pairs
27
35
 
28
36
 
29
37
  # Pagy Variables
30
- # All the Pagy::VARS here are set for all the pagy instances but can be
31
- # overridden by just passing them to Pagy.new or the pagy controller method
38
+ # All the Pagy::VARS here are set for all the Pagy instances but can be
39
+ # overridden by just passing them to Pagy.new or the #pagy controller method
32
40
 
33
- # Core variables (See https://ddnexus.github.io/pagy/api/pagy#core-variables)
41
+ # Instance variables (See https://ddnexus.github.io/pagy/api/pagy#instance-variables)
34
42
  # Pagy::VARS[:items] = 20 # default
35
43
 
36
- # Non Core Variables (See https://ddnexus.github.io/pagy/api/pagy#non-core-variables)
44
+ # Other Variables (See https://ddnexus.github.io/pagy/api/pagy#other-variables)
37
45
  # Pagy::VARS[:size] = [1,4,4,1] # default
38
46
  # Pagy::VARS[:page_param] = :page # default
39
47
  # Pagy::VARS[:params] = {} # default
@@ -41,17 +49,12 @@
41
49
  # Pagy::VARS[:link_extra] = 'data-remote="true"' # example
42
50
  # Pagy::VARS[:item_path] = 'activerecord.models.product' # example
43
51
 
44
- # Extras Non Core Variables
45
- # See https://ddnexus.github.io/pagy/extras/responsive#breakpoints
46
- # Pagy::VARS[:breakpoints] = { 0 => [1,2,2,1], 350 => [2,3,3,2], 550 => [3,4,4,3] } # example of width/size pairs
47
-
48
-
49
52
  # Pagy::Frontend::I18N Constant
50
53
  # See https://ddnexus.github.io/pagy/api/frontend#i18n
51
54
  # Pagy::Frontend::I18N[:plurals] = -> (c) {([:zero, :one][c] || :other).to_s # default
52
55
  # Pagy::Frontend::I18N.load_file('path/to/dictionary.yml') # load a custom file
53
56
 
54
57
 
55
- # Rails: extras assets path required by compact or responsive extras
58
+ # Rails: extras assets path required by compact, items qnd responsive extras
56
59
  # See https://ddnexus.github.io/pagy/extras/compact and https://ddnexus.github.io/pagy/extras/responsive
57
60
  # Rails.application.config.assets.paths << Pagy.root.join('pagy', 'extras', 'javascripts')
@@ -0,0 +1,44 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/items
2
+
3
+ class Pagy
4
+
5
+ # Default variables for this extra
6
+ VARS[:items_param] = :items
7
+ VARS[:max_items] = 100
8
+
9
+ # Handle a custom number of :items from params
10
+ module Backend ; private
11
+
12
+ alias_method :built_in_pagy_get_vars, :pagy_get_vars
13
+
14
+ def pagy_get_vars(collection, vars)
15
+ vars[:items] ||= (items = params[vars[:items_param] || VARS[:items_param]]) && # :items from :items_param
16
+ [items&.to_i, vars.key?(:max_items) ? vars[:max_items] : VARS[:max_items]].compact.min # :items capped to :max_items
17
+ built_in_pagy_get_vars(collection, vars)
18
+ end
19
+
20
+ end
21
+
22
+ module Frontend
23
+
24
+ # this works with all Rack-based frameworks (Sinatra, Padrino, Rails, ...)
25
+ def pagy_url_for(page, pagy)
26
+ p_vars = pagy.vars; params = request.GET.merge(p_vars[:page_param] => page, p_vars[:items_param] => p_vars[:items], **p_vars[:params])
27
+ "#{request.path}?#{Rack::Utils.build_nested_query(pagy_get_params(params))}#{p_vars[:anchor]}"
28
+ end
29
+
30
+ # return the items selector HTML. For example "Show [20] items per page"
31
+ def pagy_items_selector(pagy, id=caller(1,1)[0].hash)
32
+ pagy = pagy.clone; p_vars = pagy.vars; p_items = p_vars[:items]; p_vars[:items] = "#{MARKER}-items-"
33
+
34
+ tags = %(<span id="pagy-items-#{id}">)
35
+
36
+ tags << %(<a href="#{pagy_url_for("#{MARKER}-page-", pagy)}"></a>)
37
+ 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;">)
38
+ tags << %(#{pagy_t('pagy.items.show'.freeze)} #{input} #{pagy_t('pagy.items.items'.freeze)})
39
+
40
+ tags << %(</span><script>PagyItems('#{id}', '#{MARKER}', #{pagy.from});</script>)
41
+ end
42
+
43
+ end
44
+ end
@@ -1,3 +1,5 @@
1
+ // See the Pagy documentation: https://ddnexus.github.io/pagy/extras/compact
2
+
1
3
  function PagyCompact(id, marker, page){
2
4
  var pagyNav = document.getElementById('pagy-nav-'+id),
3
5
  input = pagyNav.getElementsByTagName('input')[0],
@@ -11,5 +13,11 @@ function PagyCompact(id, marker, page){
11
13
  }
12
14
  };
13
15
 
14
- input.addEventListener("focusout", this.go);
16
+ // select the content on click: easier for typing a number
17
+ input.addEventListener('click', function(){ this.select() });
18
+ // jump to page number from input when the input looses focus
19
+ input.addEventListener('focusout', this.go);
20
+ // … and when pressing enter inside the input
21
+ input.addEventListener('keyup', function(e){ if (e.which === 13) this.go() }.bind(this));
22
+
15
23
  }
@@ -0,0 +1,26 @@
1
+ // See the Pagy documentation: https://ddnexus.github.io/pagy/extras/items
2
+
3
+ function PagyItems(id, marker, from){
4
+ var pagyNav = document.getElementById('pagy-items-'+id),
5
+ input = pagyNav.getElementsByTagName('input')[0],
6
+ current = input.value,
7
+ link = pagyNav.getElementsByTagName('a')[0];
8
+
9
+ this.go = function(){
10
+ var items = input.value;
11
+ if (current !== items) {
12
+ var page = Math.max(Math.ceil(from / items),1);
13
+ var href = link.getAttribute('href').replace(marker+'-page-', page).replace(marker+'-items-', items);
14
+ link.setAttribute('href', href);
15
+ link.click();
16
+ }
17
+ };
18
+
19
+ // select the content on click: easier for typing a number
20
+ input.addEventListener('click', function(){ this.select() });
21
+ // jump to page number from input when the input looses focus
22
+ input.addEventListener('focusout', this.go);
23
+ // … and when pressing enter inside the input
24
+ input.addEventListener('keyup', function(e){ if (e.which === 13) this.go() }.bind(this));
25
+
26
+ }
@@ -1,3 +1,5 @@
1
+ // See the Pagy documentation: https://ddnexus.github.io/pagy/extras/resposive
2
+
1
3
  function PagyResponsive(id, items, widths, series){
2
4
  var pagyNav = document.getElementById('pagy-nav-'+id),
3
5
  pagyBox = pagyNav.firstChild || pagyNav,
@@ -1,10 +1,10 @@
1
- # See the Pagy Extras documentation: https://ddnexus.github.io/pagy/extras
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/responsive
2
2
 
3
3
  require 'json'
4
4
 
5
5
  class Pagy
6
6
 
7
- # default :breakpoints
7
+ # Default :breakpoints
8
8
  VARS[:breakpoints] = { 0 => [1,4,4,1] }
9
9
 
10
10
  # Helper for building the page_nav with javascript. For example:
@@ -26,7 +26,7 @@ class Pagy
26
26
  end
27
27
 
28
28
 
29
- # return examples: "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total"
29
+ # Return examples: "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total"
30
30
  def pagy_info(pagy)
31
31
  name = pagy_t(pagy.vars[:item_path], count: pagy.count)
32
32
  path = pagy.pages == 1 ? 'pagy.info.single_page'.freeze : 'pagy.info.multiple_pages'.freeze
@@ -41,13 +41,14 @@ class Pagy
41
41
  end
42
42
 
43
43
 
44
- # sub-method called only by #pagy_url_for: here for easy customization of params by overriding
44
+ # Sub-method called only by #pagy_url_for: here for easy customization of params by overriding
45
45
  def pagy_get_params(params) params end
46
46
 
47
47
 
48
48
  MARKER = "-pagy-#{'pagy'.hash}-".freeze
49
49
 
50
- # returns a performance optimized proc to generate the HTML links
50
+ # Returns a performance optimized proc to generate the HTML links
51
+ # Benchmarked on a 20 link nav: it is ~27x faster and uses ~13x less memory than rails' link_to
51
52
  def pagy_link_proc(pagy, link_extra=''.freeze)
52
53
  p_prev, p_next = pagy.prev, pagy.next
53
54
  a, b = %(<a href="#{pagy_url_for(MARKER, pagy)}" #{pagy.vars[:link_extra]} #{link_extra}).split(MARKER, 2)
@@ -62,7 +63,7 @@ class Pagy
62
63
  def I18N.load_file(file) I18N_DATA.replace(YAML.load_file(file).first[1]) end
63
64
 
64
65
  # Similar to I18n.t for interpolation and pluralization but without translation
65
- # Use only for single-language apps: it is specialized for pagy and 5x faster than I18n.t
66
+ # Use only for single-language apps: it is specialized for Pagy and 5x faster than I18n.t
66
67
  # See also https://ddnexus.github.io/pagy/extras/i18n to use the standard I18n gem instead
67
68
  def pagy_t(path, vars={})
68
69
  value = I18N_DATA.dig(*path.to_s.split('.'.freeze)) or return %(translation missing: "#{path}")
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: 0.8.6
4
+ version: 0.9.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: 2018-06-05 00:00:00.000000000 Z
11
+ date: 2018-06-17 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,
@@ -29,7 +29,9 @@ files:
29
29
  - lib/pagy/extras/compact.rb
30
30
  - lib/pagy/extras/i18n.rb
31
31
  - lib/pagy/extras/initializer_example.rb
32
+ - lib/pagy/extras/items.rb
32
33
  - lib/pagy/extras/javascripts/pagy-compact.js
34
+ - lib/pagy/extras/javascripts/pagy-items.js
33
35
  - lib/pagy/extras/javascripts/pagy-responsive.js
34
36
  - lib/pagy/extras/responsive.rb
35
37
  - lib/pagy/extras/templates/nav.html.erb