Skip to content

Commit

Permalink
CHANGED LinkRenderer to receive collection, options and reference to …
Browse files Browse the repository at this point in the history
…view template NOT in constructor, but with the #prepare method.

This is a step towards supporting passing of LinkRenderer (or subclass) instances that may be preconfigured in some way.
  • Loading branch information
mislav committed Apr 29, 2008
1 parent 5586e8e commit 2e45f01
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 40 deletions.
58 changes: 30 additions & 28 deletions lib/will_paginate/view_helpers.rb
Expand Up @@ -49,12 +49,13 @@ module ViewHelpers
# * <tt>:param_name</tt> -- parameter name for page number in URLs (default: <tt>:page</tt>)
# * <tt>:params</tt> -- additional parameters when generating pagination links
# (eg. <tt>:controller => "foo", :action => nil</tt>)
# * <tt>:renderer</tt> -- class name of the link renderer (default: WillPaginate::LinkRenderer)
# * <tt>:renderer</tt> -- class name, class or instance of a link renderer (default:
# <tt>WillPaginate::LinkRenderer</tt>)
# * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
# * <tt>:container</tt> -- toggles rendering of the DIV container for pagination links, set to
# false only when you are rendering your own pagination markup (default: true)
# * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID automatically
# generated from the class name of objects in collection: for example, paginating
# * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID
# automatically generated from the class name of objects in collection: for example, paginating
# ArticleComment models would yield an ID of "article_comments_pagination".
#
# All options beside listed ones are passed as HTML attributes to the container
Expand Down Expand Up @@ -91,19 +92,18 @@ def will_paginate(collection = nil, options = {})
return nil unless WillPaginate::ViewHelpers.total_pages_for_collection(collection) > 1

options = options.symbolize_keys.reverse_merge WillPaginate::ViewHelpers.pagination_options
# create the renderer instance

# get the renderer instance
renderer = case options[:renderer]
when String, Class
renderer_class = options[:renderer].to_s.constantize
renderer_class.new collection, options, self
when String
options[:renderer].to_s.constantize.new
when Class
options[:renderer].new
else
returning(options[:renderer]) do |r|
r.collection = collection
r.options = options
r.template = self
end
options[:renderer]
end
# render HTML for pagination
renderer.prepare collection, options, self
renderer.to_html
end

Expand Down Expand Up @@ -179,16 +179,26 @@ def total_pages; page_count; end
# links. It is used by +will_paginate+ helper internally.
class LinkRenderer

attr_accessor :collection, :options, :template

# The gap in page links is represented by:
#
# <span class="gap">&hellip;</span>
attr_accessor :gap_marker

def initialize
@gap_marker = '<span class="gap">&hellip;</span>'
end

# * +collection+ is a WillPaginate::Collection instance or any other object
# that conforms to that API
# * +options+ are forwarded from +will_paginate+ view helper
# * +template+ is the reference to the template being rendered
def initialize(collection, options, template)
def prepare(collection, options, template)
@collection = collection
@options = options
@template = template

# reset values in case we're re-using this instance
@total_pages = @param_name = @url_string = nil
end

# Process it! This method returns the complete HTML string which contains
Expand All @@ -197,8 +207,8 @@ def initialize(collection, options, template)
def to_html
links = @options[:page_links] ? windowed_links : []
# previous/next buttons
links.unshift page_link_or_span(@collection.previous_page, %w(disabled prev_page), @options[:prev_label])
links.push page_link_or_span(@collection.next_page, %w(disabled next_page), @options[:next_label])
links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:prev_label])
links.push page_link_or_span(@collection.next_page, 'disabled next_page', @options[:next_label])

html = links.join(@options[:separator])
@options[:container] ? @template.content_tag(:div, html, html_attributes) : html
Expand All @@ -218,13 +228,6 @@ def html_attributes

protected

# The gap in page links is represented by:
#
# <span class="gap">&hellip;</span>
def gap_marker
'<span class="gap">&hellip;</span>'
end

# Collects link items for visible page numbers.
def windowed_links
prev = nil
Expand Down Expand Up @@ -267,12 +270,12 @@ def visible_page_numbers

def page_link_or_span(page, span_class, text = nil)
text ||= page.to_s
classnames = Array[*span_class]

if page and page != current_page
page_link page, text, :rel => rel_value(page), :class => classnames[1]
classnames = span_class && span_class.index(' ') && span_class.split(' ', 2).last
page_link page, text, :rel => rel_value(page), :class => classnames
else
page_span page, text, :class => classnames.join(' ')
page_span page, text, :class => span_class
end
end

Expand All @@ -284,7 +287,6 @@ def page_span(page, text, attributes = {})
@template.content_tag :span, text, attributes
end


# Returns URL params for +page_link_or_span+, taking the current GET params
# and <tt>:params</tt> option into account.
def url_for(page)
Expand Down
27 changes: 15 additions & 12 deletions test/view_test.rb
Expand Up @@ -2,21 +2,16 @@
require 'lib/view_test_process'

class AdditionalLinkAttributesRenderer < WillPaginate::LinkRenderer
def initialize(*arguments)
if arguments.size == 3
super(*arguments)
@additional_link_attributes = {:default => 'true'}
else
@additional_link_attributes = arguments.extract_options!
end
def initialize(link_attributes = nil)
super()
@additional_link_attributes = link_attributes || { :default => 'true' }
end

def page_link(page, text, attributes = {})
@template.link_to text, url_for(page), attributes.merge(@additional_link_attributes)
end
end


class ViewTest < WillPaginate::ViewTestCase

## basic pagination ##
Expand Down Expand Up @@ -60,14 +55,22 @@ def test_will_paginate_with_options
end

def test_will_paginate_using_renderer_class
paginate({},:renderer => AdditionalLinkAttributesRenderer) do
assert_select 'a[default~=true]'
paginate({}, :renderer => AdditionalLinkAttributesRenderer) do
assert_select 'a[default=true]', 3
end
end

def test_will_paginate_using_renderer_instance
paginate({},:renderer => AdditionalLinkAttributesRenderer.new(:title => 'rendered')) do
assert_select 'a[title=rendered]'
renderer = WillPaginate::LinkRenderer.new
renderer.gap_marker = '<span class="my-gap">~~</span>'

paginate({ :per_page => 2 }, :inner_window => 0, :outer_window => 0, :renderer => renderer) do
assert_select 'span.my-gap', '~~'
end

renderer = AdditionalLinkAttributesRenderer.new(:title => 'rendered')
paginate({}, :renderer => renderer) do
assert_select 'a[title=rendered]', 3
end
end

Expand Down

0 comments on commit 2e45f01

Please sign in to comment.