2011-02-05 23:05:40 +09:00
|
|
|
module Kaminari
|
|
|
|
module Helpers
|
2011-02-05 23:09:07 +09:00
|
|
|
class Tag
|
2011-02-05 23:20:06 +09:00
|
|
|
def initialize(renderer, options = {})
|
|
|
|
@renderer, @options = renderer, renderer.options.merge(options)
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
2011-02-05 23:20:06 +09:00
|
|
|
def to_s(locals = {})
|
|
|
|
@renderer.render :partial => "kaminari/#{self.class.name.demodulize.underscore}", :locals => @options.merge(locals)
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
2011-02-05 23:20:06 +09: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 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
|
|
|
class PrevLink < Tag
|
|
|
|
def to_s
|
2011-02-05 23:20:06 +09:00
|
|
|
super :prev_url => page_url_for(@options[:current_page] - 1)
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-05 23:20:06 +09:00
|
|
|
class NextSpan < Tag
|
|
|
|
end
|
|
|
|
|
2011-02-05 23:09:07 +09:00
|
|
|
class NextLink < Tag
|
|
|
|
def to_s
|
2011-02-05 23:20:06 +09:00
|
|
|
super :next_url => page_url_for(@options[:current_page] + 1)
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class PageLink < Tag
|
|
|
|
def to_s
|
2011-02-05 23:20:06 +09:00
|
|
|
super :page_url => page_url_for(@options[:page])
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-05 23:20:06 +09:00
|
|
|
class CurrentPage < Tag
|
|
|
|
def to_s
|
|
|
|
super :page_url => page_url_for(@options[:page])
|
|
|
|
end
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
2011-02-05 23:20:06 +09:00
|
|
|
class FirstPageLink < PageLink
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
2011-02-05 23:20:06 +09:00
|
|
|
class LastPageLink < PageLink
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
|
|
|
class TruncatedSpan < Tag
|
|
|
|
end
|
|
|
|
|
2011-02-06 23:17:11 +09:00
|
|
|
class Paginator < Tag
|
|
|
|
end
|
|
|
|
|
2011-02-05 23:09:07 +09:00
|
|
|
class PaginationRenderer
|
2011-02-05 23:20:06 +09:00
|
|
|
attr_reader :options
|
2011-02-05 23:09:07 +09:00
|
|
|
|
2011-02-05 23:20:06 +09: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 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
2011-02-07 00:10:39 +09:00
|
|
|
def tagify_links
|
2011-02-05 23:20:06 +09:00
|
|
|
num_pages, current_page, left, window, right = @options[:num_pages], @options[:current_page], @left, @window, @right
|
2011-02-09 01:40:09 +09:00
|
|
|
return [] if num_pages <= 1
|
2011-02-05 23:20:06 +09:00
|
|
|
|
|
|
|
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 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
2011-02-06 23:17:11 +09:00
|
|
|
def to_s
|
|
|
|
suppress_logging_render_partial do
|
2011-02-07 10:53:48 +09:00
|
|
|
clear_content_for :kaminari_paginator_tags
|
2011-02-10 05:09:50 +09:00
|
|
|
@template.content_for :kaminari_paginator_tags, tagify_links.join.html_safe
|
2011-02-06 23:17:11 +09:00
|
|
|
Paginator.new(self).to_s
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-05 23:20:06 +09:00
|
|
|
private
|
2011-02-05 23:09:07 +09:00
|
|
|
def method_missing(meth, *args, &blk)
|
|
|
|
@template.send meth, *args, &blk
|
|
|
|
end
|
2011-02-06 21:21:13 +09:00
|
|
|
|
2011-02-07 10:53:48 +09:00
|
|
|
# dirty hack
|
2011-02-06 21:21:13 +09:00
|
|
|
def suppress_logging_render_partial(&blk)
|
|
|
|
if subscriber = ActionView::LogSubscriber.log_subscribers.detect {|ls| ls.is_a? ActionView::LogSubscriber}
|
|
|
|
class << subscriber
|
|
|
|
alias_method :render_partial_with_logging, :render_partial
|
|
|
|
# do nothing
|
|
|
|
def render_partial(event)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
ret = blk.call
|
|
|
|
class << subscriber
|
|
|
|
alias_method :render_partial, :render_partial_with_logging
|
|
|
|
undef :render_partial_with_logging
|
|
|
|
end
|
|
|
|
ret
|
|
|
|
else
|
|
|
|
blk.call
|
|
|
|
end
|
|
|
|
end
|
2011-02-07 10:53:48 +09:00
|
|
|
|
|
|
|
# another dirty hack
|
|
|
|
def clear_content_for(name)
|
|
|
|
@template.instance_variable_get('@_content_for')[name] = ActiveSupport::SafeBuffer.new
|
|
|
|
end
|
2011-02-05 23:09:07 +09:00
|
|
|
end
|
|
|
|
|
|
|
|
def paginate(scope, options = {}, &block)
|
2011-02-09 01:29:58 +09:00
|
|
|
PaginationRenderer.new self, options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages, :per_page => scope.limit_value, :remote => false)
|
2011-02-05 23:05:40 +09:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|