| Class | WillPaginate::LinkRenderer |
| In: |
lib/will_paginate/view_helpers.rb
|
| Parent: | Object |
This class does the heavy lifting of actually building the pagination links. It is used by the will_paginate helper internally.
| gap_marker | [RW] |
The gap in page links is represented by:
<span class="gap">…</span> |
# File lib/will_paginate/view_helpers.rb, line 214
214: def initialize
215: @gap_marker = '<span class="gap">…</span>'
216: end
Returns the subset of options this instance was initialized with that represent HTML attributes for the container element of pagination links.
# File lib/will_paginate/view_helpers.rb, line 246
246: def html_attributes
247: return @html_attributes if @html_attributes
248: @html_attributes = @options.except *(WillPaginate::ViewHelpers.pagination_options.keys - [:class])
249: # pagination of Post models will have the ID of "posts_pagination"
250: if @options[:container] and @options[:id] === true
251: @html_attributes[:id] = @collection.first.class.name.underscore.pluralize + '_pagination'
252: end
253: @html_attributes
254: end
# File lib/will_paginate/view_helpers.rb, line 222
222: def prepare(collection, options, template)
223: @collection = collection
224: @options = options
225: @template = template
226:
227: # reset values in case we're re-using this instance
228: @total_pages = @param_name = @url_string = nil
229: end
Process it! This method returns the complete HTML string which contains pagination links. Feel free to subclass LinkRenderer and change this method as you see fit.
# File lib/will_paginate/view_helpers.rb, line 234
234: def to_html
235: links = @options[:page_links] ? windowed_links : []
236: # previous/next buttons
237: links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:previous_label])
238: links.push page_link_or_span(@collection.next_page, 'disabled next_page', @options[:next_label])
239:
240: html = links.join(@options[:separator])
241: @options[:container] ? @template.content_tag(:div, html, html_attributes) : html
242: end
# File lib/will_paginate/view_helpers.rb, line 309
309: def page_link(page, text, attributes = {})
310: @template.link_to text, url_for(page), attributes
311: end
# File lib/will_paginate/view_helpers.rb, line 298
298: def page_link_or_span(page, span_class, text = nil)
299: text ||= page.to_s
300:
301: if page and page != current_page
302: classnames = span_class && span_class.index(' ') && span_class.split(' ', 2).last
303: page_link page, text, :rel => rel_value(page), :class => classnames
304: else
305: page_span page, text, :class => span_class
306: end
307: end
# File lib/will_paginate/view_helpers.rb, line 313
313: def page_span(page, text, attributes = {})
314: @template.content_tag :span, text, attributes
315: end
Returns URL params for page_link_or_span, taking the current GET params and :params option into account.
# File lib/will_paginate/view_helpers.rb, line 319
319: def url_for(page)
320: page_one = page == 1
321: unless @url_string and !page_one
322: @url_params = {}
323: # page links should preserve GET parameters
324: stringified_merge @url_params, @template.params if @template.request.get?
325: stringified_merge @url_params, @options[:params] if @options[:params]
326:
327: if complex = param_name.index(/[^\w-]/)
328: page_param = parse_query_parameters("#{param_name}=#{page}")
329:
330: stringified_merge @url_params, page_param
331: else
332: @url_params[param_name] = page_one ? 1 : 2
333: end
334:
335: url = @template.url_for(@url_params)
336: return url if page_one
337:
338: if complex
339: @url_string = url.sub(%r!((?:\?|&)#{CGI.escape param_name}=)#{page}!, "\\1\0")
340: return url
341: else
342: @url_string = url
343: @url_params[param_name] = 3
344: @template.url_for(@url_params).split(//).each_with_index do |char, i|
345: if char == '3' and url[i, 1] == '2'
346: @url_string[i] = "\0"
347: break
348: end
349: end
350: end
351: end
352: # finally!
353: @url_string.sub "\0", page.to_s
354: end
Calculates visible page numbers using the :inner_window and :outer_window options.
# File lib/will_paginate/view_helpers.rb, line 273
273: def visible_page_numbers
274: inner_window, outer_window = @options[:inner_window].to_i, @options[:outer_window].to_i
275: window_from = current_page - inner_window
276: window_to = current_page + inner_window
277:
278: # adjust lower or upper limit if other is out of bounds
279: if window_to > total_pages
280: window_from -= window_to - total_pages
281: window_to = total_pages
282: end
283: if window_from < 1
284: window_to += 1 - window_from
285: window_from = 1
286: window_to = total_pages if window_to > total_pages
287: end
288:
289: visible = (1..total_pages).to_a
290: left_gap = (2 + outer_window)...window_from
291: right_gap = (window_to + 1)...(total_pages - outer_window)
292: visible -= left_gap.to_a if left_gap.last - left_gap.first > 1
293: visible -= right_gap.to_a if right_gap.last - right_gap.first > 1
294:
295: visible
296: end
Collects link items for visible page numbers.
# File lib/will_paginate/view_helpers.rb, line 259
259: def windowed_links
260: prev = nil
261:
262: visible_page_numbers.inject [] do |links, n|
263: # detect gaps:
264: links << gap_marker if prev and n > prev + 1
265: links << page_link_or_span(n, 'current')
266: prev = n
267: links
268: end
269: end
# File lib/will_paginate/view_helpers.rb, line 366
366: def current_page
367: @collection.current_page
368: end
# File lib/will_paginate/view_helpers.rb, line 374
374: def param_name
375: @param_name ||= @options[:param_name].to_s
376: end
# File lib/will_paginate/view_helpers.rb, line 392
392: def parse_query_parameters(params)
393: if defined? Rack::Utils
394: # For Rails > 2.3
395: Rack::Utils.parse_nested_query(params)
396: elsif defined?(ActionController::AbstractRequest)
397: ActionController::AbstractRequest.parse_query_parameters(params)
398: elsif defined?(ActionController::UrlEncodedPairParser)
399: # For Rails > 2.2
400: ActionController::UrlEncodedPairParser.parse_query_parameters(params)
401: elsif defined?(CGIMethods)
402: CGIMethods.parse_query_parameters(params)
403: else
404: raise "unsupported ActionPack version"
405: end
406: end
# File lib/will_paginate/view_helpers.rb, line 358
358: def rel_value(page)
359: case page
360: when @collection.previous_page; 'prev' + (page == 1 ? ' start' : '')
361: when @collection.next_page; 'next'
362: when 1; 'start'
363: end
364: end
Recursively merge into target hash by using stringified keys from the other one
# File lib/will_paginate/view_helpers.rb, line 379
379: def stringified_merge(target, other)
380: other.each do |key, value|
381: key = key.to_s # this line is what it's all about!
382: existing = target[key]
383:
384: if value.is_a?(Hash) and (existing.is_a?(Hash) or existing.nil?)
385: stringified_merge(existing || (target[key] = {}), value)
386: else
387: target[key] = value
388: end
389: end
390: end