will_paginate 2.3.16 → 3.0.pre

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 (83) hide show
  1. data/CHANGELOG.rdoc +24 -80
  2. data/LICENSE +1 -1
  3. data/README.rdoc +125 -0
  4. data/Rakefile +26 -22
  5. data/lib/will_paginate/array.rb +25 -8
  6. data/lib/will_paginate/collection.rb +15 -28
  7. data/lib/will_paginate/core_ext.rb +26 -0
  8. data/lib/will_paginate/deprecation.rb +50 -0
  9. data/lib/will_paginate/finders/active_record.rb +158 -0
  10. data/lib/will_paginate/finders/active_resource.rb +51 -0
  11. data/lib/will_paginate/finders/base.rb +112 -0
  12. data/lib/will_paginate/finders/data_mapper.rb +30 -0
  13. data/lib/will_paginate/finders/sequel.rb +23 -0
  14. data/lib/will_paginate/finders.rb +9 -0
  15. data/lib/will_paginate/railtie.rb +26 -0
  16. data/lib/will_paginate/version.rb +5 -5
  17. data/lib/will_paginate/view_helpers/action_view.rb +142 -0
  18. data/lib/will_paginate/view_helpers/base.rb +126 -0
  19. data/lib/will_paginate/view_helpers/link_renderer.rb +130 -0
  20. data/lib/will_paginate/view_helpers/link_renderer_base.rb +83 -0
  21. data/lib/will_paginate/view_helpers/merb.rb +13 -0
  22. data/lib/will_paginate/view_helpers.rb +25 -436
  23. data/lib/will_paginate.rb +10 -84
  24. data/spec/collection_spec.rb +147 -0
  25. data/spec/console +8 -0
  26. data/spec/console_fixtures.rb +8 -0
  27. data/spec/database.yml +22 -0
  28. data/spec/finders/active_record_spec.rb +377 -0
  29. data/spec/finders/active_resource_spec.rb +52 -0
  30. data/spec/finders/activerecord_test_connector.rb +114 -0
  31. data/spec/finders/data_mapper_spec.rb +62 -0
  32. data/spec/finders/data_mapper_test_connector.rb +20 -0
  33. data/spec/finders/sequel_spec.rb +53 -0
  34. data/spec/finders/sequel_test_connector.rb +9 -0
  35. data/spec/finders_spec.rb +76 -0
  36. data/{test → spec}/fixtures/developer.rb +2 -3
  37. data/{test → spec}/fixtures/project.rb +2 -6
  38. data/{test → spec}/fixtures/projects.yml +1 -1
  39. data/{test → spec}/fixtures/reply.rb +1 -1
  40. data/spec/fixtures/topic.rb +7 -0
  41. data/spec/rcov.opts +2 -0
  42. data/spec/spec.opts +2 -0
  43. data/spec/spec_helper.rb +74 -0
  44. data/spec/tasks.rake +60 -0
  45. data/spec/view_helpers/action_view_spec.rb +345 -0
  46. data/spec/view_helpers/base_spec.rb +64 -0
  47. data/spec/view_helpers/link_renderer_base_spec.rb +84 -0
  48. data/spec/view_helpers/view_example_group.rb +103 -0
  49. metadata +60 -52
  50. data/README.md +0 -53
  51. data/lib/will_paginate/finder.rb +0 -264
  52. data/lib/will_paginate/i18n.rb +0 -29
  53. data/lib/will_paginate/locale/en.yml +0 -33
  54. data/lib/will_paginate/named_scope.rb +0 -170
  55. data/lib/will_paginate/named_scope_patch.rb +0 -37
  56. data/lib/will_paginate/per_page.rb +0 -27
  57. data/test/ci.rb +0 -56
  58. data/test/collection_test.rb +0 -160
  59. data/test/console +0 -8
  60. data/test/database.yml +0 -16
  61. data/test/finder_test.rb +0 -520
  62. data/test/fixtures/topic.rb +0 -12
  63. data/test/gemfiles/Gemfile.1.2 +0 -13
  64. data/test/gemfiles/Gemfile.1.2.lock +0 -39
  65. data/test/gemfiles/Gemfile.2.0 +0 -16
  66. data/test/gemfiles/Gemfile.2.0.lock +0 -28
  67. data/test/gemfiles/Gemfile.2.1 +0 -16
  68. data/test/gemfiles/Gemfile.2.1.lock +0 -28
  69. data/test/gemfiles/Gemfile.2.2 +0 -16
  70. data/test/gemfiles/Gemfile.2.2.lock +0 -28
  71. data/test/helper.rb +0 -34
  72. data/test/lib/activerecord_test_case.rb +0 -38
  73. data/test/lib/activerecord_test_connector.rb +0 -86
  74. data/test/lib/load_fixtures.rb +0 -12
  75. data/test/lib/view_test_process.rb +0 -186
  76. data/test/view_test.rb +0 -373
  77. /data/{test → spec}/fixtures/admin.rb +0 -0
  78. /data/{test → spec}/fixtures/developers_projects.yml +0 -0
  79. /data/{test → spec}/fixtures/replies.yml +0 -0
  80. /data/{test → spec}/fixtures/schema.rb +0 -0
  81. /data/{test → spec}/fixtures/topics.yml +0 -0
  82. /data/{test → spec}/fixtures/user.rb +0 -0
  83. /data/{test → spec}/fixtures/users.yml +0 -0
@@ -1,453 +1,42 @@
1
- require 'will_paginate/core_ext'
2
- require 'will_paginate/i18n'
1
+ require 'will_paginate/deprecation'
3
2
 
4
3
  module WillPaginate
5
4
  # = Will Paginate view helpers
6
5
  #
7
- # The main view helper, #will_paginate, renders
8
- # pagination links for the given collection. The helper itself is lightweight
9
- # and serves only as a wrapper around LinkRenderer instantiation; the
10
- # renderer then does all the hard work of generating the HTML.
6
+ # The main view helper is +will_paginate+. It renders the pagination links
7
+ # for the given collection. The helper itself is lightweight and serves only
8
+ # as a wrapper around LinkRenderer instantiation; the renderer then does
9
+ # all the hard work of generating the HTML.
11
10
  #
12
- # == Global options for helpers
13
- #
14
- # Options for pagination helpers are optional and get their default values from the
15
- # <tt>WillPaginate::ViewHelpers.pagination_options</tt> hash. You can write to this hash to
16
- # override default options on the global level:
17
- #
18
- # WillPaginate::ViewHelpers.pagination_options[:previous_label] = 'Previous page'
19
- #
20
- # By putting this into "config/initializers/will_paginate.rb" (or simply environment.rb in
21
- # older versions of Rails) you can easily translate link texts to previous
22
- # and next pages, as well as override some other defaults to your liking.
11
+ # Read more in WillPaginate::ViewHelpers::Base
23
12
  module ViewHelpers
24
- include WillPaginate::I18n
25
-
26
- # default options that can be overridden on the global level
27
- @@pagination_options = {
13
+ # ==== Global options for helpers
14
+ #
15
+ # Options for pagination helpers are optional and get their default values
16
+ # from the WillPaginate::ViewHelpers.pagination_options hash. You can write
17
+ # to this hash to override default options on the global level:
18
+ #
19
+ # WillPaginate::ViewHelpers.pagination_options[:previous_label] = 'Previous page'
20
+ #
21
+ # By putting this into your environment.rb you can easily translate link
22
+ # texts to previous and next pages, as well as override some other defaults
23
+ # to your liking.
24
+ def self.pagination_options() @pagination_options; end
25
+ # Overrides the default +pagination_options+
26
+ def self.pagination_options=(value) @pagination_options = value; end
27
+
28
+ self.pagination_options = {
28
29
  :class => 'pagination',
29
- :previous_label => nil,
30
- :next_label => nil,
30
+ :previous_label => '&#8592; Previous',
31
+ :next_label => 'Next &#8594;',
31
32
  :inner_window => 4, # links around the current page
32
33
  :outer_window => 1, # links around beginning and end
33
34
  :separator => ' ', # single space is friendly to spiders and non-graphic browsers
34
35
  :param_name => :page,
35
36
  :params => nil,
36
- :renderer => 'WillPaginate::LinkRenderer',
37
+ :renderer => 'WillPaginate::ViewHelpers::LinkRenderer',
37
38
  :page_links => true,
38
39
  :container => true
39
40
  }
40
- mattr_reader :pagination_options
41
-
42
- # Renders Digg/Flickr-style pagination for a WillPaginate::Collection
43
- # object. Nil is returned if there is only one page in total; no point in
44
- # rendering the pagination in that case...
45
- #
46
- # ==== Options
47
- # Display options:
48
- # * <tt>:previous_label</tt> -- default: "« Previous" (this parameter is called <tt>:prev_label</tt> in versions <b>2.3.2</b> and older!)
49
- # * <tt>:next_label</tt> -- default: "Next »"
50
- # * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
51
- # * <tt>:inner_window</tt> -- how many links are shown around the current page (default: 4)
52
- # * <tt>:outer_window</tt> -- how many links are around the first and the last page (default: 1)
53
- # * <tt>:separator</tt> -- string separator for page HTML elements (default: single space)
54
- #
55
- # HTML options:
56
- # * <tt>:class</tt> -- CSS class name for the generated DIV (default: "pagination")
57
- # * <tt>:container</tt> -- toggles rendering of the DIV container for pagination links, set to
58
- # false only when you are rendering your own pagination markup (default: true)
59
- # * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID
60
- # automatically generated from the class name of objects in collection: for example, paginating
61
- # ArticleComment models would yield an ID of "article_comments_pagination".
62
- #
63
- # Advanced options:
64
- # * <tt>:param_name</tt> -- parameter name for page number in URLs (default: <tt>:page</tt>)
65
- # * <tt>:params</tt> -- additional parameters when generating pagination links
66
- # (eg. <tt>:controller => "foo", :action => nil</tt>)
67
- # * <tt>:renderer</tt> -- class name, class or instance of a link renderer (default:
68
- # <tt>WillPaginate::LinkRenderer</tt>)
69
- #
70
- # All options not recognized by will_paginate will become HTML attributes on the container
71
- # element for pagination links (the DIV). For example:
72
- #
73
- # <%= will_paginate @posts, :style => 'font-size: small' %>
74
- #
75
- # ... will result in:
76
- #
77
- # <div class="pagination" style="font-size: small"> ... </div>
78
- #
79
- # ==== Using the helper without arguments
80
- # If the helper is called without passing in the collection object, it will
81
- # try to read from the instance variable inferred by the controller name.
82
- # For example, calling +will_paginate+ while the current controller is
83
- # PostsController will result in trying to read from the <tt>@posts</tt>
84
- # variable. Example:
85
- #
86
- # <%= will_paginate :id => true %>
87
- #
88
- # ... will result in <tt>@post</tt> collection getting paginated:
89
- #
90
- # <div class="pagination" id="posts_pagination"> ... </div>
91
- #
92
- def will_paginate(collection = nil, options = {})
93
- options, collection = collection, nil if collection.is_a? Hash
94
- unless collection or !controller
95
- collection_name = "@#{controller.controller_name}"
96
- collection = instance_variable_get(collection_name)
97
- raise ArgumentError, "The #{collection_name} variable appears to be empty. Did you " +
98
- "forget to pass the collection object for will_paginate?" unless collection
99
- end
100
- # early exit if there is nothing to render
101
- return nil unless WillPaginate::ViewHelpers.total_pages_for_collection(collection) > 1
102
-
103
- options = options.symbolize_keys.reverse_merge WillPaginate::ViewHelpers.pagination_options
104
- if options[:prev_label]
105
- WillPaginate::Deprecation::warn(":prev_label view parameter is now :previous_label; the old name has been deprecated", caller)
106
- options[:previous_label] = options.delete(:prev_label)
107
- end
108
-
109
- options[:previous_label] ||= will_paginate_translate(:previous_label) { '&laquo; Previous' }
110
- options[:next_label] ||= will_paginate_translate(:next_label) { 'Next &raquo;' }
111
-
112
- # get the renderer instance
113
- renderer = case options[:renderer]
114
- when String
115
- options[:renderer].to_s.constantize.new
116
- when Class
117
- options[:renderer].new
118
- else
119
- options[:renderer]
120
- end
121
- # render HTML for pagination
122
- renderer.prepare collection, options, self
123
- renderer.to_html
124
- end
125
-
126
- # Wrapper for rendering pagination links at both top and bottom of a block
127
- # of content.
128
- #
129
- # <% paginated_section @posts do %>
130
- # <ol id="posts">
131
- # <% for post in @posts %>
132
- # <li> ... </li>
133
- # <% end %>
134
- # </ol>
135
- # <% end %>
136
- #
137
- # will result in:
138
- #
139
- # <div class="pagination"> ... </div>
140
- # <ol id="posts">
141
- # ...
142
- # </ol>
143
- # <div class="pagination"> ... </div>
144
- #
145
- # Arguments are passed to a <tt>will_paginate</tt> call, so the same options
146
- # apply. Don't use the <tt>:id</tt> option; otherwise you'll finish with two
147
- # blocks of pagination links sharing the same ID (which is invalid HTML).
148
- def paginated_section(*args, &block)
149
- pagination = will_paginate(*args).to_s
150
-
151
- if respond_to? :output_buffer
152
- concat pagination
153
- yield
154
- concat pagination
155
- else
156
- content = pagination + capture(&block) + pagination
157
- concat(content, block.binding)
158
- end
159
- end
160
-
161
- # Renders a helpful message with numbers of displayed vs. total entries.
162
- # You can use this as a blueprint for your own, similar helpers.
163
- #
164
- # <%= page_entries_info @posts %>
165
- # #-> Displaying posts 6 - 10 of 26 in total
166
- #
167
- # By default, the message will use the humanized class name of objects
168
- # in collection: for instance, "project types" for ProjectType models.
169
- # Override this with the <tt>:model</tt> parameter:
170
- #
171
- # <%= page_entries_info @posts, :model => 'item' %>
172
- # #-> Displaying items 6 - 10 of 26 in total
173
- def page_entries_info(collection, options = {})
174
- if options.key? :entry_name
175
- WillPaginate::Deprecation::warn(":entry_name parameter is now called :model", caller)
176
- end
177
- model = options[:model] || options[:entry_name]
178
- model = collection.first.class unless model or collection.empty?
179
- model ||= 'entry'
180
-
181
- if html = options.fetch(:html, true)
182
- b, eb = '<b>', '</b>'
183
- sp = '&nbsp;'
184
- html_key = '_html'
185
- else
186
- b = eb = html_key = ''
187
- sp = ' '
188
- end
189
-
190
- model_key = model.to_s.underscore
191
- model_count = collection.total_pages > 1 ? 5 : collection.size
192
- model_name = will_paginate_translate "models.#{model_key}", :count => model_count do |_, opts|
193
- name = model_key.to_s.tr('_/', ' ')
194
- raise "can't pluralize model name: #{model.inspect}" unless name.respond_to? :pluralize
195
- opts[:count] == 1 ? name : name.pluralize
196
- end
197
-
198
- output = if collection.total_pages < 2
199
- i18n_key = :"page_entries_info.single_page#{html_key}"
200
- keys = [:"#{model_key}.#{i18n_key}", i18n_key]
201
-
202
- will_paginate_translate keys, :count => collection.size, :model => model_name do |_, opts|
203
- case opts[:count]
204
- when 0; "No #{opts[:model]} found"
205
- when 1; "Displaying #{b}1#{eb} #{opts[:model]}"
206
- else "Displaying #{b}all#{sp}#{opts[:count]}#{eb} #{opts[:model]}"
207
- end
208
- end
209
- else
210
- i18n_key = :"page_entries_info.multi_page#{html_key}"
211
- keys = [:"#{model_key}.#{i18n_key}", i18n_key]
212
- params = {
213
- :model => model_name, :count => collection.total_entries,
214
- :from => collection.offset + 1, :to => collection.offset + collection.length
215
- }
216
- will_paginate_translate keys, params do |_, opts|
217
- %{Displaying %s #{b}%d#{sp}-#{sp}%d#{eb} of #{b}%d#{eb} in total} %
218
- [ opts[:model], opts[:from], opts[:to], opts[:count] ]
219
- end
220
- end
221
-
222
- if html and output.respond_to?(:html_safe)
223
- output.html_safe
224
- else
225
- output
226
- end
227
- end
228
-
229
- def self.total_pages_for_collection(collection) #:nodoc:
230
- if collection.respond_to?('page_count') and !collection.respond_to?('total_pages')
231
- WillPaginate::Deprecation.warn %{
232
- You are using a paginated collection of class #{collection.class.name}
233
- which conforms to the old API of WillPaginate::Collection by using
234
- `page_count`, while the current method name is `total_pages`. Please
235
- upgrade yours or 3rd-party code that provides the paginated collection}, caller
236
- class << collection
237
- def total_pages; page_count; end
238
- end
239
- end
240
- collection.total_pages
241
- end
242
- end
243
-
244
- # This class does the heavy lifting of actually building the pagination
245
- # links. It is used by the <tt>will_paginate</tt> helper internally.
246
- class LinkRenderer
247
-
248
- # * +collection+ is a WillPaginate::Collection instance or any other object
249
- # that conforms to that API
250
- # * +options+ are forwarded from +will_paginate+ view helper
251
- # * +template+ is the reference to the template being rendered
252
- def prepare(collection, options, template)
253
- @collection = collection
254
- @options = options
255
- @template = template
256
-
257
- # reset values in case we're re-using this instance
258
- @total_pages = @param_name = @url_string = nil
259
- end
260
-
261
- # Process it! This method returns the complete HTML string which contains
262
- # pagination links. Feel free to subclass LinkRenderer and change this
263
- # method as you see fit.
264
- def to_html
265
- links = @options[:page_links] ? windowed_links : []
266
- # previous/next buttons
267
- links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:previous_label])
268
- links.push page_link_or_span(@collection.next_page, 'disabled next_page', @options[:next_label])
269
-
270
- html = links.join(@options[:separator])
271
- html = html.html_safe if html.respond_to? :html_safe
272
- @options[:container] ? @template.content_tag(:div, html, html_attributes) : html
273
- end
274
-
275
- # Returns the subset of +options+ this instance was initialized with that
276
- # represent HTML attributes for the container element of pagination links.
277
- def html_attributes
278
- return @html_attributes if @html_attributes
279
- @html_attributes = @options.except *(WillPaginate::ViewHelpers.pagination_options.keys - [:class])
280
- # pagination of Post models will have the ID of "posts_pagination"
281
- if @options[:container] and @options[:id] === true
282
- @html_attributes[:id] = @collection.first.class.name.underscore.pluralize + '_pagination'
283
- end
284
- @html_attributes
285
- end
286
-
287
- attr_writer :gap_marker
288
-
289
- # The gap in page links is represented by:
290
- #
291
- # <span class="gap">&hellip;</span>
292
- def gap_marker
293
- @gap_marker ||= begin
294
- gap_text = @template.will_paginate_translate(:page_gap) { '&hellip;' }
295
- %(<span class="gap">#{gap_text}</span>)
296
- end
297
- end
298
-
299
- protected
300
-
301
- # Collects link items for visible page numbers.
302
- def windowed_links
303
- prev = nil
304
-
305
- visible_page_numbers.inject [] do |links, n|
306
- # detect gaps:
307
- links << gap_marker if prev and n > prev + 1
308
- links << page_link_or_span(n, 'current')
309
- prev = n
310
- links
311
- end
312
- end
313
-
314
- # Calculates visible page numbers using the <tt>:inner_window</tt> and
315
- # <tt>:outer_window</tt> options.
316
- def visible_page_numbers
317
- inner_window, outer_window = @options[:inner_window].to_i, @options[:outer_window].to_i
318
- window_from = current_page - inner_window
319
- window_to = current_page + inner_window
320
-
321
- # adjust lower or upper limit if other is out of bounds
322
- if window_to > total_pages
323
- window_from -= window_to - total_pages
324
- window_to = total_pages
325
- end
326
- if window_from < 1
327
- window_to += 1 - window_from
328
- window_from = 1
329
- window_to = total_pages if window_to > total_pages
330
- end
331
-
332
- visible = (1..total_pages).to_a
333
- left_gap = (2 + outer_window)...window_from
334
- right_gap = (window_to + 1)...(total_pages - outer_window)
335
- visible -= left_gap.to_a if left_gap.last - left_gap.first > 1
336
- visible -= right_gap.to_a if right_gap.last - right_gap.first > 1
337
-
338
- visible
339
- end
340
-
341
- def page_link_or_span(page, span_class, text = nil)
342
- text ||= page.to_s
343
- text = text.html_safe if text.respond_to? :html_safe
344
-
345
- if page and page != current_page
346
- classnames = span_class && span_class.index(' ') && span_class.split(' ', 2).last
347
- page_link page, text, :rel => rel_value(page), :class => classnames
348
- else
349
- page_span page, text, :class => span_class
350
- end
351
- end
352
-
353
- def page_link(page, text, attributes = {})
354
- @template.link_to text, url_for(page), attributes
355
- end
356
-
357
- def page_span(page, text, attributes = {})
358
- @template.content_tag :span, text, attributes
359
- end
360
-
361
- # Returns URL params for +page_link_or_span+, taking the current GET params
362
- # and <tt>:params</tt> option into account.
363
- def url_for(page)
364
- page_one = page == 1
365
- unless @url_string and !page_one
366
- @url_params = {}
367
- # page links should preserve GET parameters
368
- stringified_merge @url_params, @template.params if @template.request.get?
369
- stringified_merge @url_params, @options[:params] if @options[:params]
370
-
371
- if complex = param_name.index(/[^\w-]/)
372
- page_param = parse_query_parameters("#{param_name}=#{page}")
373
-
374
- stringified_merge @url_params, page_param
375
- else
376
- @url_params[param_name] = page_one ? 1 : 2
377
- end
378
-
379
- url = @template.url_for(@url_params)
380
- return url if page_one
381
-
382
- if complex
383
- @url_string = url.sub(%r!((?:\?|&amp;)#{CGI.escape param_name}=)#{page}!, "\\1\0")
384
- return url
385
- else
386
- @url_string = url
387
- @url_params[param_name] = 3
388
- @template.url_for(@url_params).split(//).each_with_index do |char, i|
389
- if char == '3' and url[i, 1] == '2'
390
- @url_string[i] = "\0"
391
- break
392
- end
393
- end
394
- end
395
- end
396
- # finally!
397
- @url_string.sub "\0", page.to_s
398
- end
399
-
400
- private
401
-
402
- def rel_value(page)
403
- case page
404
- when @collection.previous_page; 'prev' + (page == 1 ? ' start' : '')
405
- when @collection.next_page; 'next'
406
- when 1; 'start'
407
- end
408
- end
409
-
410
- def current_page
411
- @collection.current_page
412
- end
413
-
414
- def total_pages
415
- @total_pages ||= WillPaginate::ViewHelpers.total_pages_for_collection(@collection)
416
- end
417
-
418
- def param_name
419
- @param_name ||= @options[:param_name].to_s
420
- end
421
-
422
- # Recursively merge into target hash by using stringified keys from the other one
423
- def stringified_merge(target, other)
424
- other.each do |key, value|
425
- key = key.to_s # this line is what it's all about!
426
- existing = target[key]
427
-
428
- if value.is_a?(Hash) and (existing.is_a?(Hash) or existing.nil?)
429
- stringified_merge(existing || (target[key] = {}), value)
430
- else
431
- target[key] = value
432
- end
433
- end
434
- end
435
-
436
- def parse_query_parameters(params)
437
- if defined? Rack::Utils
438
- # For Rails > 2.3
439
- Rack::Utils.parse_nested_query(params)
440
- elsif defined?(ActionController::AbstractRequest) and
441
- ActionController::AbstractRequest.respond_to? :parse_query_parameters
442
- ActionController::AbstractRequest.parse_query_parameters(params)
443
- elsif defined?(ActionController::UrlEncodedPairParser)
444
- # For Rails > 2.2
445
- ActionController::UrlEncodedPairParser.parse_query_parameters(params)
446
- elsif defined?(CGIMethods)
447
- CGIMethods.parse_query_parameters(params)
448
- else
449
- raise "unsupported ActionPack version"
450
- end
451
- end
452
41
  end
453
42
  end
data/lib/will_paginate.rb CHANGED
@@ -1,97 +1,23 @@
1
- require 'active_support'
2
- require 'will_paginate/core_ext'
1
+ require 'will_paginate/deprecation'
3
2
 
4
3
  # = You *will* paginate!
5
4
  #
6
- # First read about WillPaginate::Finder::ClassMethods, then see
5
+ # First read about WillPaginate::Finders::Base, then see
7
6
  # WillPaginate::ViewHelpers. The magical array you're handling in-between is
8
7
  # WillPaginate::Collection.
9
8
  #
10
9
  # Happy paginating!
11
10
  module WillPaginate
12
- class << self
13
- # shortcut for <tt>enable_actionpack</tt> and <tt>enable_activerecord</tt> combined
14
- def enable
15
- enable_actionpack
16
- enable_activerecord
17
- end
18
-
19
- # hooks WillPaginate::ViewHelpers into ActionView::Base
20
- def enable_actionpack
21
- return if ActionView::Base.instance_methods.include_method? :will_paginate
22
- require 'will_paginate/view_helpers'
23
- ActionView::Base.send :include, ViewHelpers
24
-
25
- if defined?(ActionController::Base) and ActionController::Base.respond_to? :rescue_responses
26
- ActionController::Base.rescue_responses['WillPaginate::InvalidPage'] = :not_found
27
- end
28
- end
29
-
30
- # hooks WillPaginate::Finder into ActiveRecord::Base and classes that deal
31
- # with associations
32
- def enable_activerecord
33
- return if ActiveRecord::Base.respond_to? :paginate
34
- require 'will_paginate/finder'
35
- ActiveRecord::Base.send :include, Finder
36
-
37
- # support pagination on associations
38
- a = ActiveRecord::Associations
39
- klasses = [ a::AssociationCollection ]
40
- # detect http://dev.rubyonrails.org/changeset/9230
41
- unless a::HasManyThroughAssociation.superclass == a::HasManyAssociation
42
- klasses << a::HasManyThroughAssociation
43
- end
44
-
45
- klasses.each do |klass|
46
- klass.send :include, Finder::ClassMethods
47
- klass.class_eval { alias_method_chain :method_missing, :paginate }
48
- end
49
-
50
- # monkeypatch Rails ticket #2189: "count breaks has_many :through"
51
- ActiveRecord::Base.class_eval do
52
- protected
53
- def self.construct_count_options_from_args(*args)
54
- result = super
55
- result[0] = '*' if result[0].is_a?(String) and result[0] =~ /\.\*$/
56
- result
57
- end
58
- end
59
- end
60
-
61
- # Enable named_scope, a feature of Rails 2.1, even if you have older Rails
62
- # (tested on Rails 2.0.2 and 1.2.6).
63
- #
64
- # You can pass +false+ for +patch+ parameter to skip monkeypatching
65
- # *associations*. Use this if you feel that <tt>named_scope</tt> broke
66
- # has_many, has_many :through or has_and_belongs_to_many associations in
67
- # your app. By passing +false+, you can still use <tt>named_scope</tt> in
68
- # your models, but not through associations.
69
- def enable_named_scope(patch = true)
70
- return if defined? ActiveRecord::NamedScope
71
- require 'will_paginate/named_scope'
72
- require 'will_paginate/named_scope_patch' if patch
73
-
74
- ActiveRecord::Base.send :include, WillPaginate::NamedScope
75
- end
76
- end
77
-
78
- module Deprecation # :nodoc:
79
- extend ActiveSupport::Deprecation
80
-
81
- def self.warn(message, callstack = caller)
82
- message = 'WillPaginate: ' + message.strip.gsub(/\s+/, ' ')
83
- ActiveSupport::Deprecation.warn(message, callstack)
84
- end
85
- end
86
11
  end
87
12
 
88
- if defined? Rails
89
- WillPaginate.enable_activerecord if defined? ActiveRecord
90
- WillPaginate.enable_actionpack if defined? ActionController
13
+ if defined?(::Rails::Railtie)
14
+ require 'will_paginate/railtie'
91
15
  end
92
16
 
93
- # load default translations only for newer versions of I18n
94
- if defined? I18n and not defined? I18n::Backend::Simple::MATCH
95
- require 'will_paginate/i18n'
96
- I18n.load_path.unshift(*WillPaginate::I18n.load_path)
17
+ if defined?(::Merb::Plugins)
18
+ require 'will_paginate/view_helpers/merb'
19
+ # auto-load the right ORM adapter
20
+ if adapter = { :datamapper => 'data_mapper', :activerecord => 'active_record', :sequel => 'sequel' }[Merb.orm]
21
+ require "will_paginate/finders/#{adapter}"
22
+ end
97
23
  end