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 +15 -0
- data/README.rdoc +1 -1
- data/Rakefile +13 -8
- data/lib/will_paginate/version.rb +2 -2
- data/lib/will_paginate/view_helpers.rb +58 -25
- data/test/lib/view_test_process.rb +6 -2
- data/test/view_test.rb +62 -4
- metadata +1 -1
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
|
@@ -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
|
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
|
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
|
-
|
95
|
-
|
96
|
-
renderer =
|
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
|
134
|
-
|
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;
|
138
|
-
when 1;
|
139
|
-
else; "Displaying <b>all #{collection.size}</b>
|
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
|
161
|
+
%{Displaying #{entry_name.pluralize} <b>%d - %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">…</span>
|
192
|
+
attr_accessor :gap_marker
|
193
|
+
|
194
|
+
def initialize
|
195
|
+
@gap_marker = '<span class="gap">…</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
|
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,
|
186
|
-
links.push page_link_or_span(@collection.next_page,
|
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">…</span>
|
209
|
-
def gap_marker
|
210
|
-
'<span class="gap">…</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
|
-
|
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
|
-
|
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::
|
41
|
+
if defined? ActionView::InlineTemplate
|
42
42
|
# Rails 2.1
|
43
|
-
args = [ ActionView::
|
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
|
169
|
+
assert_equal %{Displaying strings <b>6 - 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
|
173
|
+
assert_equal %{Displaying strings <b>25 - 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>
|
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>
|
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 - 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
|