pagy 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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