pagy 5.1.2 → 5.2.2

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/config/pagy.rb +17 -5
  3. data/lib/javascripts/pagy.js +1 -1
  4. data/lib/pagy/calendar.rb +148 -0
  5. data/lib/pagy/countless.rb +1 -1
  6. data/lib/pagy/exceptions.rb +2 -4
  7. data/lib/pagy/extras/arel.rb +2 -1
  8. data/lib/pagy/extras/array.rb +2 -2
  9. data/lib/pagy/extras/bootstrap.rb +1 -1
  10. data/lib/pagy/extras/bulma.rb +1 -1
  11. data/lib/pagy/extras/calendar.rb +46 -0
  12. data/lib/pagy/extras/countless.rb +3 -2
  13. data/lib/pagy/extras/elasticsearch_rails.rb +3 -2
  14. data/lib/pagy/extras/foundation.rb +2 -2
  15. data/lib/pagy/extras/gearbox.rb +3 -3
  16. data/lib/pagy/extras/headers.rb +7 -5
  17. data/lib/pagy/extras/i18n.rb +1 -1
  18. data/lib/pagy/extras/items.rb +4 -1
  19. data/lib/pagy/extras/materialize.rb +1 -1
  20. data/lib/pagy/extras/meilisearch.rb +3 -2
  21. data/lib/pagy/extras/metadata.rb +3 -2
  22. data/lib/pagy/extras/navs.rb +1 -1
  23. data/lib/pagy/extras/overflow.rb +24 -19
  24. data/lib/pagy/extras/searchkick.rb +3 -2
  25. data/lib/pagy/extras/semantic.rb +4 -4
  26. data/lib/pagy/extras/shared.rb +1 -1
  27. data/lib/pagy/extras/standalone.rb +2 -1
  28. data/lib/pagy/extras/support.rb +2 -1
  29. data/lib/pagy/extras/trim.rb +2 -1
  30. data/lib/pagy/extras/uikit.rb +2 -2
  31. data/lib/pagy/frontend.rb +9 -4
  32. data/lib/pagy/url_helpers.rb +1 -1
  33. data/lib/pagy.rb +2 -2
  34. data/lib/templates/foundation_nav.html.erb +1 -1
  35. data/lib/templates/foundation_nav.html.haml +1 -1
  36. data/lib/templates/foundation_nav.html.slim +1 -1
  37. data/lib/templates/uikit_nav.html.erb +1 -1
  38. data/lib/templates/uikit_nav.html.haml +1 -1
  39. data/lib/templates/uikit_nav.html.slim +1 -1
  40. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4af6c795ba446552a412f0f45e76a267cf767d8f4dec3564a90096525bb298ea
4
- data.tar.gz: 57a3f62877f0ed653ebe68f59963fb865e252e68c55e5c3a91794b9aa3b9584a
3
+ metadata.gz: 5cb4539d68931db35f7f2f8c9d53d9e8a63541f402f23621b92a51e6a2e77386
4
+ data.tar.gz: 4adbae6e3d5213c6628bec8a35a26c5e44ce09546fa6fdd74541d5bbf2feb63b
5
5
  SHA512:
6
- metadata.gz: 0520f9933ea293895b8d26b0a78ea0af1a61054b5b89fce3a06c1f8f292d82357f6e105f76ab7bd4665f6ee9765bc69ce284428b8fe61b8f0a6b4768136c8e4a
7
- data.tar.gz: '0903950d58220f510b5c2700b42f23f19c5cd267bc73eb5404d918863717b816836609256ef3a340534a9bc74e50260915b8b023b502c9dbe503bb443fab968f'
6
+ metadata.gz: 277754cc4da9b7bd70c173ad052c87658eda48c7a42ad28675e1b5ce3eafae09932bf3c2a1682715890bbb4039ce3484f0a1adc7f7223e6bd3702e3cfb9b0eab
7
+ data.tar.gz: 9cb4995ece3b2fe8ab5625646cb1118080d27f52ce63af8efe5fd5178a6f8e8e77e9196a7f851780057fb315368622961f70eb65f808c460d011d5d890ff69bd
data/lib/config/pagy.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Pagy initializer file (5.1.2)
3
+ # Pagy initializer file (5.2.2)
4
4
  # Customize only what you really need and notice that Pagy works also without any of the following lines.
5
5
  # Should you just cherry pick part of this file, please maintain the require-order of the extras
6
6
 
7
7
 
8
- # Pagy Variables
8
+ # Pagy DEFAULT Variables
9
9
  # See https://ddnexus.github.io/pagy/api/pagy#variables
10
- # All the Pagy::DEFAULT are set for all the Pagy instances but can be overridden
11
- # per instance by just passing them to Pagy.new or the #pagy controller method
10
+ # All the Pagy::DEFAULT are set for all the Pagy instances but can be overridden per instance
11
+ # by just passing them to Pagy.new|Pagy::Countless.new|Pagy::Calendar.new or the #pagy controller method
12
12
 
13
13
 
14
14
  # Instance variables
@@ -39,6 +39,18 @@
39
39
  # See https://ddnexus.github.io/pagy/extras/array
40
40
  # require 'pagy/extras/array'
41
41
 
42
+ # Calendar extra: Paginate a collection by calendar Time unit (year, month, week or day)
43
+ # See https://ddnexus.github.io/pagy/extras/calendar
44
+ # require 'pagy/extras/calendar'
45
+ # Pagy::DEFAULT[:local_minmax] = [] # Min and max local Time period must be set by the user (better not not as default)
46
+ # Pagy::DEFAULT[:unit] = :month # Time unit allowed %i[year month week day]
47
+ # Pagy::DEFAULT[:week_offset] = 0 # Day offset from Sunday (0: Sunday; 1: Monday;... 6: Saturday)
48
+ # Pagy::DEFAULT[:order] = :asc # Time direction of pagination
49
+ # Pagy::DEFAULT[:year_format] = '%Y' # strftime format for :year unit
50
+ # Pagy::DEFAULT[:month_format] = '%Y-%m' # strftime format for :month unit
51
+ # Pagy::DEFAULT[:week_format] = '%Y-%W' # strftime format for :week unit
52
+ # Pagy::DEFAULT[:day_format] = '%Y-%m-%d' # strftime format for :day unit
53
+
42
54
  # Countless extra: Paginate without any count, saving one query per rendering
43
55
  # See https://ddnexus.github.io/pagy/extras/countless
44
56
  # require 'pagy/extras/countless'
@@ -72,7 +84,7 @@
72
84
  # require 'pagy/extras/shared'
73
85
  # require 'pagy/extras/metadata'
74
86
  # For performance reason, you should explicitly set ONLY the metadata you use in the frontend
75
- # Pagy::DEFAULT[:metadata] = [:scaffold_url, :count, :page, :prev, :next, :last] # example
87
+ # Pagy::DEFAULT[:metadata] = %i[scaffold_url count page prev next last] # example
76
88
 
77
89
  # Searchkick extra: Paginate `Searchkick::Results` objects
78
90
  # See https://ddnexus.github.io/pagy/extras/searchkick
@@ -3,7 +3,7 @@
3
3
  // Container of the whole pagy stuff
4
4
  function Pagy(){}
5
5
 
6
- Pagy.version = '5.1.2'
6
+ Pagy.version = '5.2.2'
7
7
 
8
8
  // Used by the waitForMe function
9
9
  Pagy.delay = 100
@@ -0,0 +1,148 @@
1
+ # See Pagy::Countless API documentation: https://ddnexus.github.io/pagy/api/calendar
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy'
5
+ require 'date'
6
+
7
+ class Pagy # :nodoc:
8
+ DEFAULT[:local_minmax] = [] # Min and max Time period must be set by the user
9
+ DEFAULT[:unit] = :month # Time unit allowed %i[year month week day]
10
+ DEFAULT[:week_offset] = 0 # Day offset from Sunday (0: Sunday; 1: Monday;... 6: Saturday)
11
+ DEFAULT[:order] = :asc # Time direction of pagination
12
+ DEFAULT[:year_format] = '%Y' # strftime format for :year unit
13
+ DEFAULT[:month_format] = '%Y-%m' # strftime format for :month unit
14
+ DEFAULT[:week_format] = '%Y-%W' # strftime format for :week unit
15
+ DEFAULT[:day_format] = '%Y-%m-%d' # strftime format for :day unit
16
+
17
+ # Paginate a Time period by units (year, month, week or day)
18
+ class Calendar < Pagy
19
+ attr_reader :utc_from, :utc_to, :unit, :week_offset, :order
20
+ attr_writer :count, :in
21
+
22
+ # Merge and validate the options, do some simple arithmetic and set a few instance variables
23
+ def initialize(vars) # rubocop:disable Lint/MissingSuper
24
+ normalize_vars(vars)
25
+ setup_vars(page: 1, week_offset: 0)
26
+ setup_unit_vars
27
+ raise OverflowError.new(self, :page, "in 1..#{@last}", @page) if @page > @last
28
+
29
+ @prev = (@page - 1 unless @page == 1)
30
+ @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
31
+ end
32
+
33
+ # Generate a label for each page, with the specific `Time` period it refers to
34
+ def page_label(num = @page, format = nil)
35
+ snap = snap(num.to_i)
36
+ format ||= @vars[:"#{@unit}_format"]
37
+ case @unit
38
+ when :year then new_time(@initial.year + snap)
39
+ when :month then bump_month(@initial, snap)
40
+ when :week then @initial + (snap * WEEK)
41
+ when :day then @initial + (snap * DAY)
42
+ else raise InternalError, "expected @unit to be in [:year, :month, :week, :day]; got #{@unit.inspect}"
43
+ end.strftime(format)
44
+ end
45
+
46
+ def current_page_label(format = nil)
47
+ page_label(@page, format)
48
+ end
49
+
50
+ DAY = 60 * 60 * 24
51
+ WEEK = DAY * 7
52
+
53
+ protected
54
+
55
+ def setup_unit_vars
56
+ (units = %i[year month week day]).each do |unit|
57
+ raise VariableError.new(self, :format, 'to be a strftime format', @vars[:"#{unit}_format"]) \
58
+ unless @vars[:"#{unit}_format"].is_a?(String)
59
+ end
60
+ raise VariableError.new(self, :unit, "to be in #{units.inspect}", @unit) \
61
+ unless units.include?(@unit = @vars[:unit])
62
+ raise VariableError.new(self, :order, 'to be in [:asc, :desc]', @order) \
63
+ unless %i[asc desc].include?(@order = @vars[:order])
64
+
65
+ min, max = @vars[:local_minmax]
66
+ raise VariableError.new(self, :local_minmax, 'to be a an Array of min and max local Time instances', @vars[:local_minmax]) \
67
+ unless min.is_a?(Time) && max.is_a?(Time) && !min.utc? && !min.utc? && min <= max \
68
+ && (@utc_offset = min.utc_offset) == max.utc_offset
69
+
70
+ send :"setup_#{@unit}_vars", min, max
71
+ end
72
+
73
+ # IMPORTANT: all the Time objects created and passed as arguments MUST be local!
74
+
75
+ # @initial: beginning of the first day of the period that encloses the min local time
76
+ # @final: beginning of the first day of the NEXT period AFTER the period that encloses the max local time
77
+ # @utc_from: beginning of the first day of the period of the current page as UTC time
78
+ # @utc_to: beginning of the first day of the NEXT period AFTER the current page as UTC time
79
+
80
+ # Setup the calendar vars when the unit is :year
81
+ def setup_year_vars(min, max)
82
+ @initial = new_time(min.year)
83
+ @final = new_time(max.year + 1)
84
+ @pages = @last = @final.year - @initial.year
85
+ @utc_from = new_time(@initial.year + snap).utc
86
+ @utc_to = new_time(@initial.year + snap + 1).utc
87
+ end
88
+
89
+ # Setup the calendar vars when the unit is :month
90
+ def setup_month_vars(min, max)
91
+ @initial = new_time(min.year, min.month)
92
+ @final = bump_month(max)
93
+ @pages = @last = months(@final) - months(@initial)
94
+ @utc_from = bump_month(@initial, snap).utc
95
+ @utc_to = bump_month(@initial, snap + 1).utc
96
+ end
97
+
98
+ # Setup the calendar vars when the unit is :week
99
+ def setup_week_vars(min, max)
100
+ @initial = week_start(min)
101
+ @final = week_start(max) + WEEK
102
+ @pages = @last = (@final - @initial).to_i / WEEK
103
+ @utc_from = (@initial + (snap * WEEK)).utc
104
+ @utc_to = @utc_from + WEEK
105
+ end
106
+
107
+ # Setup the calendar vars when the unit is :day
108
+ def setup_day_vars(min, max)
109
+ @initial = new_time(min.year, min.month, min.day)
110
+ @final = new_time(max.year, max.month, max.day) + DAY
111
+ @pages = @last = (@final - @initial).to_i / DAY
112
+ @utc_from = (@initial + (snap * DAY)).utc
113
+ @utc_to = @utc_from + DAY
114
+ end
115
+
116
+ private
117
+
118
+ # Simple trick to snap the page into its ordered position,
119
+ # without actually reordering anything in the internal structure
120
+ def snap(page = @page)
121
+ @order == :asc ? page - 1 : @pages - page
122
+ end
123
+
124
+ # Create a new local time at the beginning of the day
125
+ def new_time(year, month = 1, day = 1)
126
+ Time.new(year, month, day, 0, 0, 0, @utc_offset)
127
+ end
128
+
129
+ # Months in local time
130
+ def months(time)
131
+ (time.year * 12) + time.month
132
+ end
133
+
134
+ # Add 1 or more months to local time
135
+ def bump_month(time, months = 1)
136
+ months += months(time)
137
+ year = months / 12
138
+ month = months % 12
139
+ month.zero? ? new_time(year - 1, 12) : new_time(year, month)
140
+ end
141
+
142
+ # Return the start of the week for local time
143
+ def week_start(time)
144
+ start = time - (((time.wday - @week_offset) * DAY) % WEEK)
145
+ new_time(start.year, start.month, start.day)
146
+ end
147
+ end
148
+ end
@@ -16,7 +16,7 @@ class Pagy
16
16
 
17
17
  # Finalize the instance variables based on the fetched size
18
18
  def finalize(fetched_size)
19
- raise OverflowError.new(self, :page, "to be < #{@page}") if fetched_size.zero? && @page > 1
19
+ raise OverflowError.new(self, :page, "to be < #{@page}", @page) if fetched_size.zero? && @page > 1
20
20
 
21
21
  @pages = @last = (fetched_size > @items ? @page + 1 : @page)
22
22
  @in = [fetched_size, @items].min
@@ -6,13 +6,11 @@ class Pagy
6
6
  attr_reader :pagy, :variable, :value
7
7
 
8
8
  # Set the variables and prepare the message
9
- def initialize(pagy, variable, description, value = nil)
9
+ def initialize(pagy, variable, description, value)
10
10
  @pagy = pagy
11
11
  @variable = variable
12
12
  @value = value
13
- message = +"expected :#{@variable} #{description}"
14
- message << "; got #{@value.inspect}" if value
15
- super message
13
+ super "expected :#{@variable} #{description}; got #{@value.inspect}"
16
14
  end
17
15
  end
18
16
 
@@ -1,7 +1,8 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/arel
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
+ # Better performance of grouped ActiveRecord collections
5
6
  module ArelExtra
6
7
  private
7
8
 
@@ -1,8 +1,8 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/array
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
5
- # Add specialized backend methods to paginate array collections
4
+ class Pagy # :nodoc:
5
+ # Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
6
6
  module ArrayExtra
7
7
  private
8
8
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module BootstrapExtra
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module BulmaExtra
@@ -0,0 +1,46 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/calendar
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy/calendar'
5
+
6
+ class Pagy # :nodoc:
7
+ # Paginate based on calendar periods (year month week day)
8
+ module CalendarExtra
9
+ # Additions for the Backend module
10
+ module Backend
11
+ private
12
+
13
+ # Return Pagy object and items
14
+ def pagy_calendar(collection, vars = {})
15
+ pagy = Calendar.new(pagy_calendar_get_vars(collection, vars))
16
+ [pagy, pagy_calendar_get_items(collection, pagy)]
17
+ end
18
+
19
+ # Sub-method called only by #pagy_calendar: here for easy customization of variables by overriding.
20
+ # You may want to override it in order to implement the dynamic set of the :minmax variable.
21
+ def pagy_calendar_get_vars(_collection, vars)
22
+ # vars[:minmax] ||= your_own_method_to_get_the_period_from(collection)
23
+ vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
24
+ vars
25
+ end
26
+
27
+ # This method should be implemented in the application and should return the records
28
+ # for the unit by selecting the records with DateTime from pagy.from to pagy.to
29
+ def pagy_calendar_get_items(_collection, _pagy)
30
+ # collection.your_own_method_to_get_the_items_with(pagy.from, pagy.to)
31
+ raise NoMethodError, 'The pagy_calendar_get_items method must be implemented in the application and must return ' \
32
+ 'the items for the unit by selecting the records with Time from pagy.from to pagy.to'
33
+ end
34
+ end
35
+
36
+ # Additions for the Frontend module
37
+ module Frontend
38
+ # Change the text shown in the nav bar links to the actual unit of each page.
39
+ def pagy_labeler(pagy, num)
40
+ pagy.is_a?(Calendar) ? pagy.page_label(num) : num
41
+ end
42
+ end
43
+ end
44
+ Backend.prepend CalendarExtra::Backend
45
+ Frontend.prepend CalendarExtra::Frontend
46
+ end
@@ -3,15 +3,16 @@
3
3
 
4
4
  require 'pagy/countless'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  DEFAULT[:countless_minimal] = false
8
8
 
9
+ # Paginate without the need of any count, saving one query per rendering
9
10
  module CountlessExtra
10
11
  private
11
12
 
12
13
  # Return Pagy object and items
13
14
  def pagy_countless(collection, vars = {})
14
- pagy = Pagy::Countless.new(pagy_countless_get_vars(collection, vars))
15
+ pagy = Countless.new(pagy_countless_get_vars(collection, vars))
15
16
  [pagy, pagy_countless_get_items(collection, pagy)]
16
17
  end
17
18
 
@@ -1,9 +1,10 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/elasticsearch_rails
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
5
  DEFAULT[:elasticsearch_rails_search_method] ||= :pagy_search
6
6
 
7
+ # Paginate ElasticsearchRails response objects
7
8
  module ElasticsearchRailsExtra
8
9
  module_function
9
10
 
@@ -17,7 +18,7 @@ class Pagy
17
18
  total.is_a?(Hash) ? total['value'] : total
18
19
  end
19
20
 
20
- module ElasticsearchRails
21
+ module ElasticsearchRails # :nodoc:
21
22
  # Return an array used to delay the call of #search
22
23
  # after the pagination variables are merged to the options.
23
24
  # It also pushes to the same array an optional method call.
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module FoundationExtra
@@ -17,7 +17,7 @@ class Pagy
17
17
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
18
18
  html << case item
19
19
  when Integer then %(<li>#{link.call item}</li>) # page link
20
- when String then %(<li class="current">#{item}</li>) # active page
20
+ when String then %(<li class="current">#{pagy_labeler(pagy, item)}</li>) # active page
21
21
  when :gap then %(<li class="ellipsis gap" aria-hidden="true"></li>) # page gap
22
22
  else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
23
23
  end
@@ -1,14 +1,14 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/gearbox
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
5
  DEFAULT[:gearbox_extra] = true # extra enabled by default
6
6
  DEFAULT[:gearbox_items] = [15, 30, 60, 100]
7
7
 
8
8
  # Automatically change the number of items per page depending on the page number
9
9
  # accepts an array as the :gearbox_items variable, that will determine the items for the first pages
10
10
  module GearboxExtra
11
- # Setup @items based on the :items variable
11
+ # Setup @items based on the :gearbox_items variable
12
12
  def setup_items_var
13
13
  return super if !@vars[:gearbox_extra] || @vars[:items_extra]
14
14
 
@@ -19,7 +19,7 @@ class Pagy
19
19
  @items = gearbox_items[@page - 1] || gearbox_items.last
20
20
  end
21
21
 
22
- # Setup @pages and @last based on the :items variable
22
+ # Setup @pages and @last based on the :gearbox_items variable
23
23
  def setup_pages_var
24
24
  return super if !@vars[:gearbox_extra] || @vars[:items_extra]
25
25
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/url_helpers'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  DEFAULT[:headers] = { page: 'Current-Page',
8
8
  items: 'Page-Items',
9
9
  count: 'Total-Count',
@@ -28,7 +28,7 @@ class Pagy
28
28
 
29
29
  # Generates a hash structure of the headers
30
30
  def pagy_headers_hash(pagy)
31
- countless = defined?(Pagy::Countless) && pagy.is_a?(Pagy::Countless)
31
+ countless = defined?(Countless) && pagy.is_a?(Countless)
32
32
  rel = { 'first' => 1, 'prev' => pagy.prev, 'next' => pagy.next }
33
33
  rel['last'] = pagy.last unless countless
34
34
  url_str = pagy_url_for(pagy, PAGE_PLACEHOLDER, absolute: true)
@@ -38,11 +38,13 @@ class Pagy
38
38
  end.compact.to_h
39
39
  hash = { 'Link' => link }
40
40
  headers = pagy.vars[:headers]
41
- hash[headers[:page]] = pagy.page.to_s if headers[:page]
42
- hash[headers[:items]] = pagy.vars[:items].to_s if headers[:items]
41
+ hash[headers[:page]] = pagy.page.to_s if headers[:page]
42
+ if headers[:items] && !(defined?(Calendar) && pagy.is_a?(Calendar)) # items is not for Calendar
43
+ hash[headers[:items]] = pagy.vars[:items].to_s
44
+ end
43
45
  unless countless
44
46
  hash[headers[:pages]] = pagy.pages.to_s if headers[:pages]
45
- hash[headers[:count]] = pagy.count.to_s if headers[:count]
47
+ hash[headers[:count]] = pagy.count.to_s if pagy.count && headers[:count] # count may be nil with Calendar
46
48
  end
47
49
  hash
48
50
  end
@@ -1,7 +1,7 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/i18n
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
5
  # Use ::I18n gem
6
6
  module I18nExtra
7
7
  def pagy_t(key, **opts)
@@ -3,12 +3,14 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy # Default variables for this extra
6
+ class Pagy # :nodoc:
7
7
  DEFAULT[:items_param] = :items
8
8
  DEFAULT[:max_items] = 100
9
9
  DEFAULT[:items_extra] = true # extra enabled by default
10
10
 
11
+ # Allow the client to request a custom number of items per page with an optional selector UI
11
12
  module ItemsExtra
13
+ # Additions for the Backend module
12
14
  module Backend
13
15
  private
14
16
 
@@ -22,6 +24,7 @@ class Pagy # Default variables for this extra
22
24
  end
23
25
  end
24
26
 
27
+ # Additions for the Frontend module
25
28
  module Frontend
26
29
  ITEMS_PLACEHOLDER = '__pagy_items__'
27
30
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module MaterializeExtra
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Pagy
3
+ class Pagy # :nodoc:
4
4
  DEFAULT[:meilisearch_search_method] ||= :pagy_search
5
5
 
6
+ # Paginate Meilisearch results
6
7
  module MeilisearchExtra
7
- module Meilisearch
8
+ module Meilisearch # :nodoc:
8
9
  # Return an array used to delay the call of #search
9
10
  # after the pagination variables are merged to the options
10
11
  def pagy_meilisearch(term = nil, **vars)
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/url_helpers'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  DEFAULT[:metadata] = %i[ scaffold_url first_url prev_url page_url next_url last_url
8
8
  count page items vars pages last in from to prev next series ]
9
9
 
@@ -17,7 +17,8 @@ class Pagy
17
17
  def pagy_metadata(pagy, absolute: nil)
18
18
  scaffold_url = pagy_url_for(pagy, PAGE_PLACEHOLDER, absolute: absolute)
19
19
  {}.tap do |metadata|
20
- pagy.vars[:metadata].each do |key|
20
+ keys = defined?(Calendar) && pagy.is_a?(Calendar) ? pagy.vars[:metadata] - %i[count items] : pagy.vars[:metadata]
21
+ keys.each do |key|
21
22
  metadata[key] = case key
22
23
  when :scaffold_url then scaffold_url
23
24
  when :first_url then scaffold_url.sub(PAGE_PLACEHOLDER, 1.to_s)
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module NavsExtra
@@ -1,10 +1,10 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/overflow
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
5
  DEFAULT[:overflow] = :empty_page
6
6
 
7
- # Handles OverflowError exceptions with different options
7
+ # Handles OverflowError exceptions for different classes with different options
8
8
  module OverflowExtra
9
9
  # Support for Pagy class
10
10
  module Pagy
@@ -15,21 +15,25 @@ class Pagy
15
15
 
16
16
  # Add rescue clause for different behaviors
17
17
  def initialize(vars)
18
- @overflow ||= false # don't override if :last_page re-run the method after an overflow
18
+ @overflow ||= false # still true if :last_page re-run the method after an overflow
19
19
  super
20
20
  rescue OverflowError
21
- @overflow = true # add the overflow flag
21
+ @overflow = true # add the overflow flag
22
22
  case @vars[:overflow]
23
23
  when :exception
24
- raise # same as without the extra
24
+ raise # same as without the extra
25
25
  when :last_page
26
- initial_page = @vars[:page] # save the very initial page (even after re-run)
27
- initialize vars.merge!(page: @last) # re-run with the last page
28
- @vars[:page] = initial_page # restore the initial page
26
+ requested_page = @vars[:page] # save the requested page (even after re-run)
27
+ initialize vars.merge!(page: @last) # re-run with the last page
28
+ @vars[:page] = requested_page # restore the requested page
29
29
  when :empty_page
30
- @offset = @items = @from = @to = 0 # vars relative to the actual page
31
- @prev = @last # prev relative to the actual page
32
- extend Series # special series for :empty_page
30
+ @offset = @in = @from = @to = 0 # vars relative to the actual page
31
+ if defined?(Calendar) && is_a?(Calendar) # only for Calendar instances
32
+ edge = @order == :asc ? @final : @initial # get the edge of the overflow side (neat, but it would work with any time)
33
+ @utc_from = @utc_to = edge.getutc # set both to the edge utc time (a query with >= && < will get no record)
34
+ end
35
+ @prev = @last # prev relative to the actual page
36
+ extend Series # special series for :empty_page
33
37
  else
34
38
  raise VariableError.new(self, :overflow, 'to be in [:last_page, :empty_page, :exception]', @vars[:overflow])
35
39
  end
@@ -38,10 +42,10 @@ class Pagy
38
42
  # Special series for empty page
39
43
  module Series
40
44
  def series(size = @vars[:size])
41
- @page = @last # series for last page
42
- super(size).tap do |s| # call original series
43
- s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
44
- @page = @vars[:page] # restore the actual page
45
+ @page = @last # series for last page
46
+ super(size).tap do |s| # call original series
47
+ s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
48
+ @page = @vars[:page] # restore the actual page
45
49
  end
46
50
  end
47
51
  end
@@ -54,13 +58,13 @@ class Pagy
54
58
  @overflow = false
55
59
  super
56
60
  rescue OverflowError
57
- @overflow = true # add the overflow flag
61
+ @overflow = true # add the overflow flag
58
62
  case @vars[:overflow]
59
63
  when :exception
60
- raise # same as without the extra
64
+ raise # same as without the extra
61
65
  when :empty_page
62
- @offset = @items = @from = @to = 0 # vars relative to the actual page
63
- @vars[:size] = [] # no page in the series
66
+ @offset = @in = @from = @to = 0 # vars relative to the actual page
67
+ @vars[:size] = [] # no page in the series
64
68
  self
65
69
  else
66
70
  raise VariableError.new(self, :overflow, 'to be in [:empty_page, :exception]', @vars[:overflow])
@@ -69,5 +73,6 @@ class Pagy
69
73
  end
70
74
  end
71
75
  prepend OverflowExtra::Pagy
76
+ Calendar.prepend OverflowExtra::Pagy if defined?(Calendar)
72
77
  Countless.prepend OverflowExtra::Countless if defined?(Countless)
73
78
  end
@@ -1,11 +1,12 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/searchkick
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
5
  DEFAULT[:searchkick_search_method] ||= :pagy_search
6
6
 
7
+ # Paginate Searchkick::Results objects
7
8
  module SearchkickExtra
8
- module Searchkick
9
+ module Searchkick # :nodoc:
9
10
  # Return an array used to delay the call of #search
10
11
  # after the pagination variables are merged to the options.
11
12
  # It also pushes to the same array an optional method call.
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module SemanticExtra
@@ -16,9 +16,9 @@ class Pagy
16
16
  html << pagy_semantic_prev_html(pagy, link)
17
17
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
18
18
  html << case item
19
- when Integer then link.call item # page link
20
- when String then %(<a class="item active">#{item}</a>) # current page
21
- when :gap then %(<div class="disabled item">#{pagy_t 'pagy.nav.gap'}</div>) # page gap
19
+ when Integer then link.call item
20
+ when String then %(<a class="item active">#{pagy_labeler(pagy, item)}</a>)
21
+ when :gap then %(<div class="disabled item">#{pagy_t 'pagy.nav.gap'}</div>)
22
22
  else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
23
23
  end
24
24
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'digest'
4
4
 
5
- class Pagy
5
+ class Pagy # :nodoc:
6
6
  DEFAULT[:steps] = false # default false will use {0 => @vars[:size]}
7
7
 
8
8
  module SharedExtra
@@ -2,7 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'uri'
5
- class Pagy
5
+
6
+ class Pagy # :nodoc:
6
7
  # Use pagy without any request object, nor Rack environment/gem, nor any defined params method,
7
8
  # even in the irb/rails console without any app or config.
8
9
  module StandaloneExtra
@@ -1,7 +1,8 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/support
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
+ # Extra support for features like: incremental, auto-incremental and infinite pagination
5
6
  module SupportExtra
6
7
  # Return the previous page URL string or nil
7
8
  def pagy_prev_url(pagy)
@@ -1,9 +1,10 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/trim
2
2
  # frozen_string_literal: true
3
3
 
4
- class Pagy
4
+ class Pagy # :nodoc:
5
5
  DEFAULT[:trim_extra] = true # extra enabled by default
6
6
 
7
+ # Remove the page=1 param from the first page link
7
8
  module TrimExtra
8
9
  # Override the original pagy_link_proc.
9
10
  # Call the pagy_trim method if the trim_extra is enabled.
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'pagy/extras/shared'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module UikitExtra
@@ -16,7 +16,7 @@ class Pagy
16
16
  pagy.series.each do |item|
17
17
  html << case item
18
18
  when Integer then %(<li>#{link.call item}</li>)
19
- when String then %(<li class="uk-active"><span>#{item}</span></li>)
19
+ when String then %(<li class="uk-active"><span>#{pagy_labeler(pagy, item)}</span></li>)
20
20
  when :gap then %(<li class="uk-disabled"><span>#{pagy_t 'pagy.nav.gap'}</span></li>)
21
21
  else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
22
22
  end
data/lib/pagy/frontend.rb CHANGED
@@ -28,9 +28,9 @@ class Pagy
28
28
  end
29
29
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
30
30
  html << case item
31
- when Integer then %(<span class="page">#{link.call item}</span> ) # page link
32
- when String then %(<span class="page active">#{item}</span> ) # current page
33
- when :gap then %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> ) # page gap
31
+ when Integer then %(<span class="page">#{link.call item}</span> )
32
+ when String then %(<span class="page active">#{pagy_labeler(pagy, item)}</span> )
33
+ when :gap then %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> )
34
34
  else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
35
35
  end
36
36
  end
@@ -64,7 +64,7 @@ class Pagy
64
64
  p_next = pagy.next
65
65
  left, right = %(<a href="#{pagy_url_for pagy, PAGE_PLACEHOLDER}" #{
66
66
  pagy.vars[:link_extra]} #{link_extra}).split(PAGE_PLACEHOLDER, 2)
67
- lambda do |num, text = num, extra_attrs = ''|
67
+ lambda do |num, text = pagy_labeler(pagy, num), extra_attrs = ''|
68
68
  %(#{left}#{num}#{right}#{ case num
69
69
  when p_prev then ' rel="prev"'
70
70
  when p_next then ' rel="next"'
@@ -73,6 +73,11 @@ class Pagy
73
73
  end
74
74
  end
75
75
 
76
+ # Allow customization of the output by overriding (used by the calendar extra)
77
+ def pagy_labeler(_pagy, num)
78
+ num
79
+ end
80
+
76
81
  # Similar to I18n.t: just ~18x faster using ~10x less memory
77
82
  # (@pagy_locale explicitly initialized in order to avoid warning)
78
83
  def pagy_t(key, **opts)
@@ -8,7 +8,7 @@ class Pagy
8
8
  # For non-rack environments you can use the standalone extra
9
9
  def pagy_url_for(pagy, page, absolute: nil)
10
10
  vars = pagy.vars
11
- params = request.params.merge(vars[:params].transform_keys(&:to_s))
11
+ params = request.GET.merge(vars[:params].transform_keys(&:to_s))
12
12
  params[vars[:page_param].to_s] = page
13
13
  params[vars[:items_param].to_s] = vars[:items] if vars[:items_extra]
14
14
 
data/lib/pagy.rb CHANGED
@@ -5,7 +5,7 @@ require 'pathname'
5
5
 
6
6
  # Core class
7
7
  class Pagy
8
- VERSION = '5.1.2'
8
+ VERSION = '5.2.2'
9
9
 
10
10
  # Root pathname to get the path of Pagy files like templates or dictionaries
11
11
  def self.root
@@ -46,7 +46,7 @@ class Pagy
46
46
  def series(size = @vars[:size])
47
47
  return [] if size.empty?
48
48
  raise VariableError.new(self, :size, 'to contain 4 items >= 0', size) \
49
- unless size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
49
+ unless size.is_a?(Array) && size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
50
50
 
51
51
  # This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
52
52
  left_gap_start = 1 + size[0] # rubocop:disable Layout/ExtraSpacing, Layout/SpaceAroundOperators
@@ -13,7 +13,7 @@
13
13
  <% end -%>
14
14
  <% pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] -%>
15
15
  <% if item.is_a?(Integer) -%> <li><%== link.call(item) %></li>
16
- <% elsif item.is_a?(String) -%> <li class="current"><%= item %></li>
16
+ <% elsif item.is_a?(String) -%> <li class="current"><%= pagy_labeler(pagy, item) %></li>
17
17
  <% elsif item == :gap -%> <li class="ellipsis gap" aria-hidden="true"></li>
18
18
  <% end -%>
19
19
  <% end -%>
@@ -22,7 +22,7 @@
22
22
 
23
23
  - elsif item.is_a?(String) # current page
24
24
  %li.current
25
- = item
25
+ = pagy_labeler(pagy, item)
26
26
 
27
27
  - elsif item == :gap # page gap
28
28
  %li.ellipsis.gap{"aria-hidden" => true}
@@ -22,7 +22,7 @@ nav.pagy-foundation-nav role="navigation" aria-label="Pagination"
22
22
 
23
23
  - elsif item.is_a?(String) # current page
24
24
  li.current
25
- = item
25
+ = pagy_labeler(pagy, item)
26
26
 
27
27
  - elsif item == :gap # page gap
28
28
  li.ellipsis.gap aria-hidden="true"
@@ -5,7 +5,7 @@
5
5
  <% end -%>
6
6
  <% pagy.series.each do |item| -%>
7
7
  <% if item.is_a?(Integer) -%> <li><%== link.call(item) %></li>
8
- <% elsif item.is_a?(String) -%> <li class="uk-active"><span><%== item %></span></li>
8
+ <% elsif item.is_a?(String) -%> <li class="uk-active"><span><%== pagy_labeler(pagy, item) %></span></li>
9
9
  <% elsif item == :gap -%> <li class="uk-disabled"><span><%== pagy_t('pagy.nav.gap') %></span></li>
10
10
  <% end -%>
11
11
  <% end -%>
@@ -14,7 +14,7 @@
14
14
 
15
15
  - elsif item.is_a?(String)
16
16
  %li.uk-active
17
- %span!= item
17
+ %span!= pagy_labeler(pagy, item)
18
18
 
19
19
  - elsif item == :gap
20
20
  %li.uk-disabled
@@ -14,7 +14,7 @@ ul.uk-pagination.uk-flex-center
14
14
 
15
15
  - elsif item.is_a?(String)
16
16
  li.uk-active
17
- span== item
17
+ span== pagy_labeler(pagy, item)
18
18
 
19
19
  - elsif item == :gap
20
20
  li.uk-disabled
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: 5.1.2
4
+ version: 5.2.2
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-10-25 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Agnostic pagination in plain ruby. It does it all. Better.
14
14
  email:
@@ -53,6 +53,7 @@ files:
53
53
  - lib/locales/zh-TW.yml
54
54
  - lib/pagy.rb
55
55
  - lib/pagy/backend.rb
56
+ - lib/pagy/calendar.rb
56
57
  - lib/pagy/console.rb
57
58
  - lib/pagy/countless.rb
58
59
  - lib/pagy/exceptions.rb
@@ -60,6 +61,7 @@ files:
60
61
  - lib/pagy/extras/array.rb
61
62
  - lib/pagy/extras/bootstrap.rb
62
63
  - lib/pagy/extras/bulma.rb
64
+ - lib/pagy/extras/calendar.rb
63
65
  - lib/pagy/extras/countless.rb
64
66
  - lib/pagy/extras/elasticsearch_rails.rb
65
67
  - lib/pagy/extras/foundation.rb