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 210 210: def initialize 211: @gap_marker = '<span class="gap">…</span>' 212: 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 242 242: def html_attributes 243: return @html_attributes if @html_attributes 244: @html_attributes = @options.except *(WillPaginate::ViewHelpers.pagination_options.keys - [:class]) 245: # pagination of Post models will have the ID of "posts_pagination" 246: if @options[:container] and @options[:id] === true 247: @html_attributes[:id] = @collection.first.class.name.underscore.pluralize + '_pagination' 248: end 249: @html_attributes 250: end
# File lib/will_paginate/view_helpers.rb, line 218 218: def prepare(collection, options, template) 219: @collection = collection 220: @options = options 221: @template = template 222: 223: # reset values in case we're re-using this instance 224: @total_pages = @param_name = @url_string = nil 225: 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 230 230: def to_html 231: links = @options[:page_links] ? windowed_links : [] 232: # previous/next buttons 233: links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:previous_label]) 234: links.push page_link_or_span(@collection.next_page, 'disabled next_page', @options[:next_label]) 235: 236: html = links.join(@options[:separator]) 237: @options[:container] ? @template.content_tag(:div, html, html_attributes) : html 238: end
# File lib/will_paginate/view_helpers.rb, line 305 305: def page_link(page, text, attributes = {}) 306: @template.link_to text, url_for(page), attributes 307: end
# File lib/will_paginate/view_helpers.rb, line 294 294: def page_link_or_span(page, span_class, text = nil) 295: text ||= page.to_s 296: 297: if page and page != current_page 298: classnames = span_class && span_class.index(' ') && span_class.split(' ', 2).last 299: page_link page, text, :rel => rel_value(page), :class => classnames 300: else 301: page_span page, text, :class => span_class 302: end 303: end
# File lib/will_paginate/view_helpers.rb, line 309 309: def page_span(page, text, attributes = {}) 310: @template.content_tag :span, text, attributes 311: 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 315 315: def url_for(page) 316: page_one = page == 1 317: unless @url_string and !page_one 318: @url_params = {} 319: # page links should preserve GET parameters 320: stringified_merge @url_params, @template.params if @template.request.get? 321: stringified_merge @url_params, @options[:params] if @options[:params] 322: 323: if complex = param_name.index(/[^\w-]/) 324: page_param = (defined?(CGIMethods) ? CGIMethods : ActionController::AbstractRequest). 325: parse_query_parameters("#{param_name}=#{page}") 326: 327: stringified_merge @url_params, page_param 328: else 329: @url_params[param_name] = page_one ? 1 : 2 330: end 331: 332: url = @template.url_for(@url_params) 333: return url if page_one 334: 335: if complex 336: @url_string = url.sub(%r!((?:\?|&)#{CGI.escape param_name}=)#{page}!, '\1@') 337: return url 338: else 339: @url_string = url 340: @url_params[param_name] = 3 341: @template.url_for(@url_params).split(//).each_with_index do |char, i| 342: if char == '3' and url[i, 1] == '2' 343: @url_string[i] = '@' 344: break 345: end 346: end 347: end 348: end 349: # finally! 350: @url_string.sub '@', page.to_s 351: end
Calculates visible page numbers using the :inner_window and :outer_window options.
# File lib/will_paginate/view_helpers.rb, line 269 269: def visible_page_numbers 270: inner_window, outer_window = @options[:inner_window].to_i, @options[:outer_window].to_i 271: window_from = current_page - inner_window 272: window_to = current_page + inner_window 273: 274: # adjust lower or upper limit if other is out of bounds 275: if window_to > total_pages 276: window_from -= window_to - total_pages 277: window_to = total_pages 278: end 279: if window_from < 1 280: window_to += 1 - window_from 281: window_from = 1 282: window_to = total_pages if window_to > total_pages 283: end 284: 285: visible = (1..total_pages).to_a 286: left_gap = (2 + outer_window)...window_from 287: right_gap = (window_to + 1)...(total_pages - outer_window) 288: visible -= left_gap.to_a if left_gap.last - left_gap.first > 1 289: visible -= right_gap.to_a if right_gap.last - right_gap.first > 1 290: 291: visible 292: end
Collects link items for visible page numbers.
# File lib/will_paginate/view_helpers.rb, line 255 255: def windowed_links 256: prev = nil 257: 258: visible_page_numbers.inject [] do |links, n| 259: # detect gaps: 260: links << gap_marker if prev and n > prev + 1 261: links << page_link_or_span(n, 'current') 262: prev = n 263: links 264: end 265: end
# File lib/will_paginate/view_helpers.rb, line 363 363: def current_page 364: @collection.current_page 365: end
# File lib/will_paginate/view_helpers.rb, line 371 371: def param_name 372: @param_name ||= @options[:param_name].to_s 373: end
# File lib/will_paginate/view_helpers.rb, line 355 355: def rel_value(page) 356: case page 357: when @collection.previous_page; 'prev' + (page == 1 ? ' start' : '') 358: when @collection.next_page; 'next' 359: when 1; 'start' 360: end 361: end
Recursively merge into target hash by using stringified keys from the other one
# File lib/will_paginate/view_helpers.rb, line 376 376: def stringified_merge(target, other) 377: other.each do |key, value| 378: key = key.to_s # this line is what it's all about! 379: existing = target[key] 380: 381: if value.is_a?(Hash) and (existing.is_a?(Hash) or existing.nil?) 382: stringified_merge(existing || (target[key] = {}), value) 383: else 384: target[key] = value 385: end 386: end 387: end