kaminari--kaminari/lib/kaminari/helpers.rb

106 lines
2.8 KiB
Ruby
Raw Normal View History

module Kaminari
module Helpers
2011-02-05 14:09:07 +00:00
class Tag
2011-02-05 14:20:06 +00:00
def initialize(renderer, options = {})
@renderer, @options = renderer, renderer.options.merge(options)
2011-02-05 14:09:07 +00:00
end
2011-02-05 14:20:06 +00:00
def to_s(locals = {})
@renderer.render :partial => "kaminari/#{self.class.name.demodulize.underscore}", :locals => @options.merge(locals)
2011-02-05 14:09:07 +00:00
end
2011-02-05 14:20:06 +00:00
private
def page_url_for(page)
@renderer.url_for @renderer.params.merge(:page => (page <= 1 ? nil : page))
end
end
class PrevSpan < Tag
2011-02-05 14:09:07 +00:00
end
class PrevLink < Tag
def to_s
2011-02-05 14:20:06 +00:00
super :prev_url => page_url_for(@options[:current_page] - 1)
2011-02-05 14:09:07 +00:00
end
end
2011-02-05 14:20:06 +00:00
class NextSpan < Tag
end
2011-02-05 14:09:07 +00:00
class NextLink < Tag
def to_s
2011-02-05 14:20:06 +00:00
super :next_url => page_url_for(@options[:current_page] + 1)
2011-02-05 14:09:07 +00:00
end
end
class PageLink < Tag
def to_s
2011-02-05 14:20:06 +00:00
super :page_url => page_url_for(@options[:page])
2011-02-05 14:09:07 +00:00
end
end
2011-02-05 14:20:06 +00:00
class CurrentPage < Tag
def to_s
super :page_url => page_url_for(@options[:page])
end
2011-02-05 14:09:07 +00:00
end
2011-02-05 14:20:06 +00:00
class FirstPageLink < PageLink
2011-02-05 14:09:07 +00:00
end
2011-02-05 14:20:06 +00:00
class LastPageLink < PageLink
2011-02-05 14:09:07 +00:00
end
class TruncatedSpan < Tag
end
class PaginationRenderer
2011-02-05 14:20:06 +00:00
attr_reader :options
2011-02-05 14:09:07 +00:00
2011-02-05 14:20:06 +00:00
def initialize(template, options)
@template, @options = template, options
@left, @window, @right = (options[:left] || options[:outer_window] || 1), (options[:window] || options[:inner_window] || 4), (options[:right] || options[:outer_window] || 1)
2011-02-05 14:09:07 +00:00
end
def to_s
2011-02-05 14:20:06 +00:00
@template.content_tag :div, :class => 'pagination' do
tagify.join("\n").html_safe
end
end
2011-02-05 14:09:07 +00:00
2011-02-05 14:20:06 +00:00
def tagify
num_pages, current_page, left, window, right = @options[:num_pages], @options[:current_page], @left, @window, @right
tags = []
tags << (current_page > 1 ? PrevLink.new(self) : PrevSpan.new(self))
1.upto(num_pages) do |i|
if i == current_page
tags << CurrentPage.new(self, :page => i)
elsif (i <= left + 1) || ((num_pages - i) <= right) || ((i - current_page).abs <= window)
case i
when 1
tags << FirstPageLink.new(self, :page => i)
when num_pages
tags << LastPageLink.new(self, :page => i)
else
tags << PageLink.new(self, :page => i)
end
else
tags << TruncatedSpan.new(self) unless tags.last.is_a? TruncatedSpan
end
end
tags << (num_pages > current_page ? NextLink.new(self) : NextSpan.new(self))
2011-02-05 14:09:07 +00:00
end
2011-02-05 14:20:06 +00:00
private
2011-02-05 14:09:07 +00:00
def method_missing(meth, *args, &blk)
@template.send meth, *args, &blk
end
end
def paginate(scope, options = {}, &block)
2011-02-05 14:20:06 +00:00
PaginationRenderer.new self, options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages)
end
end
end