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

132 lines
4.3 KiB
Ruby
Raw Normal View History

2011-02-10 18:45:43 +00:00
require File.join(File.dirname(__FILE__), 'tags')
module Kaminari
module Helpers
2011-02-05 14:09:07 +00:00
class PaginationRenderer
attr_reader :options, :params
2011-02-05 14:09:07 +00:00
2011-02-10 23:22:59 +00:00
def initialize(template, options) #:nodoc:
2011-02-05 14:20:06 +00:00
@template, @options = template, options
@params = options[:params] ? template.params.merge(options.delete :params) : template.params
2011-02-05 14:20:06 +00:00
@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 current_page(page)
CurrentPage.new self, :page => page
end
def page_link(page)
case page
when 1
FirstPageLink
when @options[:num_pages]
LastPageLink
else
PageLink
end.new self, :page => page
end
%w[prev_link prev_span next_link next_span truncated_span].each do |tag|
eval <<-DEF
def #{tag}
#{tag.classify}.new self
end
DEF
end
2011-02-10 23:22:59 +00:00
def tagify_links #:nodoc:
2011-02-05 14:20:06 +00:00
num_pages, current_page, left, window, right = @options[:num_pages], @options[:current_page], @left, @window, @right
return [] if num_pages <= 1
2011-02-05 14:20:06 +00:00
tags = []
tags << (current_page > 1 ? prev_link : prev_span)
2011-02-05 14:20:06 +00:00
1.upto(num_pages) do |i|
if i == current_page
tags << current_page(i)
2011-02-05 14:20:06 +00:00
elsif (i <= left + 1) || ((num_pages - i) <= right) || ((i - current_page).abs <= window)
tags << page_link(i)
2011-02-05 14:20:06 +00:00
else
tags << truncated_span unless tags.last.is_a? TruncatedSpan
2011-02-05 14:20:06 +00:00
end
end
tags << (num_pages > current_page ? next_link : next_span)
2011-02-05 14:09:07 +00:00
end
def partial_exists?(name) #:nodoc:
resolver = context.instance_variable_get('@view_paths').first
resolver.find_all(*args_for_lookup(name)).present?
end
2011-02-10 23:22:59 +00:00
def to_s #:nodoc:
2011-02-06 14:17:11 +00:00
suppress_logging_render_partial do
clear_content_for :kaminari_paginator_tags
@template.content_for :kaminari_paginator_tags, tagify_links.join.html_safe
2011-02-06 14:17:11 +00:00
Paginator.new(self).to_s
end
end
2011-02-05 14:20:06 +00:00
private
def context
@template.instance_variable_get('@lookup_context')
end
def args_for_lookup(name)
if (method = context.method :args_for_lookup).arity == 3
# 3.0
method.call name, 'kaminari', true
else
# 3.1
method.call name, 'kaminari', true, []
end
end
2011-02-05 14:09:07 +00:00
def method_missing(meth, *args, &blk)
@template.send meth, *args, &blk
end
# dirty hack
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
# another dirty hack
def clear_content_for(name)
@template.instance_variable_get('@_content_for')[name] = ActiveSupport::SafeBuffer.new
end
2011-02-05 14:09:07 +00:00
end
2011-02-10 23:22:59 +00:00
# = Helpers
#
# A helper that renders the pagination links.
#
# <%= paginate @articles %>
#
# ==== Options
# * <tt>:window</tt> - The "inner window" size (2 by default).
# * <tt>:outer_window</tt> - The "outer window" size (1 by default).
# * <tt>:left</tt> - The "left outer window" size (1 by default).
# * <tt>:right</tt> - The "right outer window" size (1 by default).
# * <tt>:params</tt> - url_for parameters for the links (:controller, :action, etc.)
2011-02-10 23:22:59 +00:00
# * <tt>:remote</tt> - Ajax? (false by default)
# * <tt>:ANY_OTHER_VALUES</tt> - Any other hash key & values would be directly passed into each tag as :locals value.
2011-02-05 14:09:07 +00:00
def paginate(scope, options = {}, &block)
PaginationRenderer.new self, options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages, :per_page => scope.limit_value, :remote => false)
end
end
end