mislav-will_paginate 2.2.3 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,18 @@
1
+ == 2.3.0, released 2008-04-29
2
+
3
+ * Changed LinkRenderer to receive collection, options and reference to view template NOT in
4
+ constructor, but with the #prepare method. This is a step towards supporting passing of
5
+ LinkRenderer (or subclass) instances that may be preconfigured in some way
6
+ * LinkRenderer now has #page_link and #page_span methods for easier customization of output in
7
+ subclasses
8
+ * Changed page_entries_info() method to adjust its output according to humanized class name of
9
+ collection items. Override this with :entry_name parameter (singular).
10
+
11
+ page_entries_info(@posts)
12
+ #-> "Displaying all 12 posts"
13
+ page_entries_info(@posts, :entry_name => 'item')
14
+ #-> "Displaying all 12 items"
15
+
1
16
  == 2.2.3, released 2008-04-26
2
17
 
3
18
  * will_paginate gem is no longer published on RubyForge, but on
data/README.rdoc CHANGED
@@ -113,7 +113,7 @@ contributions or just simply awesome ideas:
113
113
  Chris Wanstrath, Dr. Nic Williams, K. Adam Christensen, Mike Garey, Bence
114
114
  Golda, Matt Aimonetti, Charles Brian Quinn, Desi McAdam, James Coglan, Matijs
115
115
  van Zuijlen, Maria, Brendan Ribera, Todd Willey, Bryan Helmkamp, Jan Berkel,
116
- Lourens Naudé, Rick Olson, Russell Norris.
116
+ Lourens Naudé, Rick Olson, Russell Norris, Piotr Usewicz, Chris Eppstein.
117
117
 
118
118
 
119
119
  == Usable pagination in the UI
data/Rakefile CHANGED
@@ -72,10 +72,13 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
72
72
  rdoc.options << '--webcvs=http://github.com/mislav/will_paginate/tree/master/'
73
73
  end
74
74
 
75
+ desc %{Update ".manifest" with the latest list of project filenames. Respect\
76
+ .gitignore by excluding everything that git ignores. Update `files` and\
77
+ `test_files` arrays in "*.gemspec" file if it's present.}
75
78
  task :manifest do
76
79
  list = Dir['**/*'].sort
77
80
  spec_file = Dir['*.gemspec'].first
78
- list -= [spec_file]
81
+ list -= [spec_file] if spec_file
79
82
 
80
83
  File.read('.gitignore').each_line do |glob|
81
84
  glob = glob.chomp.sub(/^\//, '')
@@ -84,14 +87,16 @@ task :manifest do
84
87
  puts "excluding #{glob}"
85
88
  end
86
89
 
87
- spec = File.read spec_file
88
- spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
89
- assignment = $1
90
- bunch = $2 ? list.grep(/^test\//) : list
91
- '%s%%w(%s)' % [assignment, bunch.join(' ')]
90
+ if spec_file
91
+ spec = File.read spec_file
92
+ spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
93
+ assignment = $1
94
+ bunch = $2 ? list.grep(/^test\//) : list
95
+ '%s%%w(%s)' % [assignment, bunch.join(' ')]
96
+ end
97
+
98
+ File.open(spec_file, 'w') {|f| f << spec }
92
99
  end
93
-
94
- File.open(spec_file, 'w') {|f| f << spec }
95
100
  File.open('.manifest', 'w') {|f| f << list.join("\n") }
96
101
  end
97
102
 
@@ -1,8 +1,8 @@
1
1
  module WillPaginate #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 2
4
- MINOR = 2
5
- TINY = 3
4
+ MINOR = 3
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -49,12 +49,13 @@ module WillPaginate
49
49
  # * <tt>:param_name</tt> -- parameter name for page number in URLs (default: <tt>:page</tt>)
50
50
  # * <tt>:params</tt> -- additional parameters when generating pagination links
51
51
  # (eg. <tt>:controller => "foo", :action => nil</tt>)
52
- # * <tt>:renderer</tt> -- class name of the link renderer (default: WillPaginate::LinkRenderer)
52
+ # * <tt>:renderer</tt> -- class name, class or instance of a link renderer (default:
53
+ # <tt>WillPaginate::LinkRenderer</tt>)
53
54
  # * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
54
55
  # * <tt>:container</tt> -- toggles rendering of the DIV container for pagination links, set to
55
56
  # false only when you are rendering your own pagination markup (default: true)
56
- # * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID automatically
57
- # generated from the class name of objects in collection: for example, paginating
57
+ # * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID
58
+ # automatically generated from the class name of objects in collection: for example, paginating
58
59
  # ArticleComment models would yield an ID of "article_comments_pagination".
59
60
  #
60
61
  # All options beside listed ones are passed as HTML attributes to the container
@@ -91,10 +92,18 @@ module WillPaginate
91
92
  return nil unless WillPaginate::ViewHelpers.total_pages_for_collection(collection) > 1
92
93
 
93
94
  options = options.symbolize_keys.reverse_merge WillPaginate::ViewHelpers.pagination_options
94
- # create the renderer instance
95
- renderer_class = options[:renderer].to_s.constantize
96
- renderer = renderer_class.new collection, options, self
95
+
96
+ # get the renderer instance
97
+ renderer = case options[:renderer]
98
+ when String
99
+ options[:renderer].to_s.constantize.new
100
+ when Class
101
+ options[:renderer].new
102
+ else
103
+ options[:renderer]
104
+ end
97
105
  # render HTML for pagination
106
+ renderer.prepare collection, options, self
98
107
  renderer.to_html
99
108
  end
100
109
 
@@ -130,16 +139,26 @@ module WillPaginate
130
139
  # You can use this as a blueprint for your own, similar helpers.
131
140
  #
132
141
  # <%= page_entries_info @posts %>
133
- # #-> Displaying entries 6 - 10 of 26 in total
134
- def page_entries_info(collection)
142
+ # #-> Displaying posts 6 - 10 of 26 in total
143
+ #
144
+ # By default, the message will use the humanized class name of objects
145
+ # in collection: for instance, "project types" for ProjectType models.
146
+ # Override this to your liking with the <tt>:entry_name</tt> parameter:
147
+ #
148
+ # <%= page_entries_info @posts, :entry_name => 'item' %>
149
+ # #-> Displaying items 6 - 10 of 26 in total
150
+ def page_entries_info(collection, options = {})
151
+ entry_name = options[:entry_name] ||
152
+ (collection.empty?? 'entry' : collection.first.class.name.underscore.sub('_', ' '))
153
+
135
154
  if collection.total_pages < 2
136
155
  case collection.size
137
- when 0; 'No entries found'
138
- when 1; 'Displaying <b>1</b> entry'
139
- else; "Displaying <b>all #{collection.size}</b> entries"
156
+ when 0; "No #{entry_name.pluralize} found"
157
+ when 1; "Displaying <b>1</b> #{entry_name}"
158
+ else; "Displaying <b>all #{collection.size}</b> #{entry_name.pluralize}"
140
159
  end
141
160
  else
142
- %{Displaying entries <b>%d&nbsp;-&nbsp;%d</b> of <b>%d</b> in total} % [
161
+ %{Displaying #{entry_name.pluralize} <b>%d&nbsp;-&nbsp;%d</b> of <b>%d</b> in total} % [
143
162
  collection.offset + 1,
144
163
  collection.offset + collection.length,
145
164
  collection.total_entries
@@ -166,14 +185,27 @@ module WillPaginate
166
185
  # This class does the heavy lifting of actually building the pagination
167
186
  # links. It is used by +will_paginate+ helper internally.
168
187
  class LinkRenderer
188
+
189
+ # The gap in page links is represented by:
190
+ #
191
+ # <span class="gap">&hellip;</span>
192
+ attr_accessor :gap_marker
193
+
194
+ def initialize
195
+ @gap_marker = '<span class="gap">&hellip;</span>'
196
+ end
197
+
169
198
  # * +collection+ is a WillPaginate::Collection instance or any other object
170
199
  # that conforms to that API
171
200
  # * +options+ are forwarded from +will_paginate+ view helper
172
201
  # * +template+ is the reference to the template being rendered
173
- def initialize(collection, options, template)
202
+ def prepare(collection, options, template)
174
203
  @collection = collection
175
204
  @options = options
176
205
  @template = template
206
+
207
+ # reset values in case we're re-using this instance
208
+ @total_pages = @param_name = @url_string = nil
177
209
  end
178
210
 
179
211
  # Process it! This method returns the complete HTML string which contains
@@ -182,8 +214,8 @@ module WillPaginate
182
214
  def to_html
183
215
  links = @options[:page_links] ? windowed_links : []
184
216
  # previous/next buttons
185
- links.unshift page_link_or_span(@collection.previous_page, %w(disabled prev_page), @options[:prev_label])
186
- links.push page_link_or_span(@collection.next_page, %w(disabled next_page), @options[:next_label])
217
+ links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:prev_label])
218
+ links.push page_link_or_span(@collection.next_page, 'disabled next_page', @options[:next_label])
187
219
 
188
220
  html = links.join(@options[:separator])
189
221
  @options[:container] ? @template.content_tag(:div, html, html_attributes) : html
@@ -203,13 +235,6 @@ module WillPaginate
203
235
 
204
236
  protected
205
237
 
206
- # The gap in page links is represented by:
207
- #
208
- # <span class="gap">&hellip;</span>
209
- def gap_marker
210
- '<span class="gap">&hellip;</span>'
211
- end
212
-
213
238
  # Collects link items for visible page numbers.
214
239
  def windowed_links
215
240
  prev = nil
@@ -252,15 +277,23 @@ module WillPaginate
252
277
 
253
278
  def page_link_or_span(page, span_class, text = nil)
254
279
  text ||= page.to_s
255
- classnames = Array[*span_class]
256
280
 
257
281
  if page and page != current_page
258
- @template.link_to text, url_for(page), :rel => rel_value(page), :class => classnames[1]
282
+ classnames = span_class && span_class.index(' ') && span_class.split(' ', 2).last
283
+ page_link page, text, :rel => rel_value(page), :class => classnames
259
284
  else
260
- @template.content_tag :span, text, :class => classnames.join(' ')
285
+ page_span page, text, :class => span_class
261
286
  end
262
287
  end
263
288
 
289
+ def page_link(page, text, attributes = {})
290
+ @template.link_to text, url_for(page), attributes
291
+ end
292
+
293
+ def page_span(page, text, attributes = {})
294
+ @template.content_tag :span, text, attributes
295
+ end
296
+
264
297
  # Returns URL params for +page_link_or_span+, taking the current GET params
265
298
  # and <tt>:params</tt> option into account.
266
299
  def url_for(page)
@@ -38,9 +38,9 @@ class WillPaginate::ViewTestCase < Test::Unit::TestCase
38
38
 
39
39
  locals = { :collection => collection, :options => options }
40
40
 
41
- if defined? ActionView::Template
41
+ if defined? ActionView::InlineTemplate
42
42
  # Rails 2.1
43
- args = [ ActionView::Template.new(@view, @template, false, locals, true, nil) ]
43
+ args = [ ActionView::InlineTemplate.new(@view, @template, locals) ]
44
44
  else
45
45
  # older Rails versions
46
46
  args = [nil, @template, nil, locals]
@@ -130,6 +130,10 @@ class DummyController
130
130
  @request = DummyRequest.new
131
131
  @url = ActionController::UrlRewriter.new(@request, @request.params)
132
132
  end
133
+
134
+ def params
135
+ @request.params
136
+ end
133
137
 
134
138
  def url_for(params)
135
139
  @url.rewrite(params)
data/test/view_test.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  require 'helper'
2
2
  require 'lib/view_test_process'
3
3
 
4
+ class AdditionalLinkAttributesRenderer < WillPaginate::LinkRenderer
5
+ def initialize(link_attributes = nil)
6
+ super()
7
+ @additional_link_attributes = link_attributes || { :default => 'true' }
8
+ end
9
+
10
+ def page_link(page, text, attributes = {})
11
+ @template.link_to text, url_for(page), attributes.merge(@additional_link_attributes)
12
+ end
13
+ end
14
+
4
15
  class ViewTest < WillPaginate::ViewTestCase
5
16
 
6
17
  ## basic pagination ##
@@ -43,6 +54,26 @@ class ViewTest < WillPaginate::ViewTestCase
43
54
  end
44
55
  end
45
56
 
57
+ def test_will_paginate_using_renderer_class
58
+ paginate({}, :renderer => AdditionalLinkAttributesRenderer) do
59
+ assert_select 'a[default=true]', 3
60
+ end
61
+ end
62
+
63
+ def test_will_paginate_using_renderer_instance
64
+ renderer = WillPaginate::LinkRenderer.new
65
+ renderer.gap_marker = '<span class="my-gap">~~</span>'
66
+
67
+ paginate({ :per_page => 2 }, :inner_window => 0, :outer_window => 0, :renderer => renderer) do
68
+ assert_select 'span.my-gap', '~~'
69
+ end
70
+
71
+ renderer = AdditionalLinkAttributesRenderer.new(:title => 'rendered')
72
+ paginate({}, :renderer => renderer) do
73
+ assert_select 'a[title=rendered]', 3
74
+ end
75
+ end
76
+
46
77
  def test_prev_next_links_have_classnames
47
78
  paginate do |pagination|
48
79
  assert_select 'span.disabled.prev_page:first-child'
@@ -135,27 +166,54 @@ class ViewTest < WillPaginate::ViewTestCase
135
166
  array = ('a'..'z').to_a
136
167
 
137
168
  paginate array.paginate(:page => 2, :per_page => 5)
138
- assert_equal %{Displaying entries <b>6&nbsp;-&nbsp;10</b> of <b>26</b> in total},
169
+ assert_equal %{Displaying strings <b>6&nbsp;-&nbsp;10</b> of <b>26</b> in total},
139
170
  @html_result
140
171
 
141
172
  paginate array.paginate(:page => 7, :per_page => 4)
142
- assert_equal %{Displaying entries <b>25&nbsp;-&nbsp;26</b> of <b>26</b> in total},
173
+ assert_equal %{Displaying strings <b>25&nbsp;-&nbsp;26</b> of <b>26</b> in total},
143
174
  @html_result
144
175
  end
145
176
 
177
+ def test_page_entries_info_with_longer_class_name
178
+ @template = '<%= page_entries_info collection %>'
179
+ collection = ('a'..'z').to_a.paginate
180
+ collection.first.stubs(:class).returns(mock('class', :name => 'ProjectType'))
181
+
182
+ paginate collection
183
+ assert @html_result.index('project types'), "expected <#{@html_result.inspect}> to mention 'project types'"
184
+ end
185
+
146
186
  def test_page_entries_info_with_single_page_collection
147
187
  @template = '<%= page_entries_info collection %>'
148
188
 
149
189
  paginate(('a'..'d').to_a.paginate(:page => 1, :per_page => 5))
150
- assert_equal %{Displaying <b>all 4</b> entries}, @html_result
190
+ assert_equal %{Displaying <b>all 4</b> strings}, @html_result
151
191
 
152
192
  paginate(['a'].paginate(:page => 1, :per_page => 5))
153
- assert_equal %{Displaying <b>1</b> entry}, @html_result
193
+ assert_equal %{Displaying <b>1</b> string}, @html_result
154
194
 
155
195
  paginate([].paginate(:page => 1, :per_page => 5))
156
196
  assert_equal %{No entries found}, @html_result
157
197
  end
158
198
 
199
+ def test_page_entries_info_with_custom_entry_name
200
+ @template = '<%= page_entries_info collection, :entry_name => "author" %>'
201
+
202
+ entries = (1..20).to_a
203
+
204
+ paginate(entries.paginate(:page => 1, :per_page => 5))
205
+ assert_equal %{Displaying authors <b>1&nbsp;-&nbsp;5</b> of <b>20</b> in total}, @html_result
206
+
207
+ paginate(entries.paginate(:page => 1, :per_page => 20))
208
+ assert_equal %{Displaying <b>all 20</b> authors}, @html_result
209
+
210
+ paginate(['a'].paginate(:page => 1, :per_page => 5))
211
+ assert_equal %{Displaying <b>1</b> author}, @html_result
212
+
213
+ paginate([].paginate(:page => 1, :per_page => 5))
214
+ assert_equal %{No authors found}, @html_result
215
+ end
216
+
159
217
  ## parameter handling in page links ##
160
218
 
161
219
  def test_will_paginate_preserves_parameters_on_get
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mislav-will_paginate
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Mislav Marohni\xC4\x87"