2011-02-10 18:45:43 +00:00
|
|
|
require File.join(File.dirname(__FILE__), 'tags')
|
|
|
|
|
2011-02-05 14:05:40 +00:00
|
|
|
module Kaminari
|
|
|
|
module Helpers
|
2011-02-27 14:25:16 +00:00
|
|
|
# The main container tag
|
|
|
|
class Paginator < Tag
|
2011-02-16 14:24:31 +00:00
|
|
|
def initialize(template, options) #:nodoc:
|
2011-02-27 14:25:16 +00:00
|
|
|
@window_options = {}.tap do |h|
|
|
|
|
h[:window] = options.delete(:window) || options.delete(:inner_window) || 4
|
|
|
|
outer_window = options.delete(:outer_window)
|
|
|
|
h[:left] = options.delete(:left) || outer_window || 0
|
|
|
|
h[:right] = options.delete(:right) || outer_window || 0
|
|
|
|
end
|
2011-02-27 14:14:32 +00:00
|
|
|
@template, @options = template, options
|
2011-02-27 15:17:09 +00:00
|
|
|
@options[:current_page] = PageProxy.new @window_options.merge(@options), @options[:current_page], nil
|
2011-02-27 14:25:16 +00:00
|
|
|
# so that this instance can actually "render". Black magic?
|
|
|
|
@output_buffer = ActionView::OutputBuffer.new
|
|
|
|
end
|
|
|
|
|
|
|
|
# render given block as a view template
|
|
|
|
def render(&block)
|
|
|
|
instance_eval &block if @options[:num_pages] > 1
|
|
|
|
@output_buffer
|
|
|
|
end
|
|
|
|
|
|
|
|
# enumerate each page providing PageProxy object as the block parameter
|
|
|
|
def each_page
|
2011-04-17 16:40:38 +00:00
|
|
|
return to_enum(:each_page) unless block_given?
|
|
|
|
|
2011-02-27 14:25:16 +00:00
|
|
|
1.upto(@options[:num_pages]) do |i|
|
|
|
|
yield PageProxy.new(@window_options.merge(@options), i, @last)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def page_tag(page)
|
|
|
|
@last = Page.new @template, @options.merge(:page => page)
|
|
|
|
end
|
|
|
|
|
|
|
|
%w[first_page prev_page next_page last_page gap].each do |tag|
|
|
|
|
eval <<-DEF
|
|
|
|
def #{tag}_tag
|
|
|
|
@last = #{tag.classify}.new @template, @options
|
|
|
|
end
|
|
|
|
DEF
|
2011-02-16 14:24:31 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s #:nodoc:
|
|
|
|
suppress_logging_render_partial do
|
2011-02-27 14:25:16 +00:00
|
|
|
super @window_options.merge(@options).merge :paginator => self
|
2011-02-16 14:24:31 +00:00
|
|
|
end
|
2011-02-05 14:09:07 +00:00
|
|
|
end
|
2011-02-06 12:21:13 +00:00
|
|
|
|
2011-02-16 14:24:31 +00:00
|
|
|
private
|
2011-02-07 01:53:48 +00:00
|
|
|
# dirty hack
|
2011-02-06 12:21:13 +00: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
|
2011-02-16 14:24:31 +00:00
|
|
|
def render_partial(event); end
|
2011-02-06 12:21:13 +00:00
|
|
|
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-27 14:25:16 +00:00
|
|
|
|
|
|
|
# Wraps a "page number" and provides some utility methods
|
|
|
|
class PageProxy
|
|
|
|
include Comparable
|
|
|
|
|
|
|
|
def initialize(options, page, last) #:nodoc:
|
|
|
|
@options, @page, @last = options, page, last
|
|
|
|
end
|
|
|
|
|
|
|
|
# the page number
|
|
|
|
def number
|
|
|
|
@page
|
|
|
|
end
|
|
|
|
|
|
|
|
# current page or not
|
|
|
|
def current?
|
|
|
|
@page == @options[:current_page]
|
|
|
|
end
|
|
|
|
|
|
|
|
# the first page or not
|
|
|
|
def first?
|
|
|
|
@page == 1
|
|
|
|
end
|
|
|
|
|
|
|
|
# the last page or not
|
|
|
|
def last?
|
|
|
|
@page == @options[:num_pages]
|
|
|
|
end
|
|
|
|
|
|
|
|
# the previous page or not
|
|
|
|
def prev?
|
|
|
|
@page == @options[:current_page] - 1
|
|
|
|
end
|
|
|
|
|
|
|
|
# the next page or not
|
|
|
|
def next?
|
|
|
|
@page == @options[:current_page] + 1
|
|
|
|
end
|
|
|
|
|
|
|
|
# within the left outer window or not
|
|
|
|
def left_outer?
|
|
|
|
@page <= @options[:left]
|
|
|
|
end
|
|
|
|
|
|
|
|
# within the right outer window or not
|
|
|
|
def right_outer?
|
|
|
|
@options[:num_pages] - @page < @options[:right]
|
|
|
|
end
|
|
|
|
|
|
|
|
# inside the inner window or not
|
|
|
|
def inside_window?
|
2011-02-27 15:17:09 +00:00
|
|
|
(@options[:current_page] - @page).abs <= @options[:window]
|
2011-02-27 14:25:16 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# The last rendered tag was "truncated" or not
|
|
|
|
def was_truncated?
|
|
|
|
@last.is_a? Gap
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_i
|
|
|
|
number
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s
|
|
|
|
number.to_s
|
|
|
|
end
|
|
|
|
|
2011-02-27 15:17:09 +00:00
|
|
|
def +(other)
|
|
|
|
to_i + other.to_i
|
|
|
|
end
|
|
|
|
|
|
|
|
def -(other)
|
|
|
|
to_i - other.to_i
|
|
|
|
end
|
|
|
|
|
2011-02-27 14:25:16 +00:00
|
|
|
def <=>(other)
|
|
|
|
to_i <=> other.to_i
|
|
|
|
end
|
|
|
|
end
|
2011-02-05 14:09:07 +00:00
|
|
|
end
|
2011-02-05 14:05:40 +00:00
|
|
|
end
|
|
|
|
end
|