diff --git a/gemfiles/active_record_51.gemfile b/gemfiles/active_record_51.gemfile
index 28262dc..49318c5 100644
--- a/gemfiles/active_record_51.gemfile
+++ b/gemfiles/active_record_51.gemfile
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
gem 'railties', '~> 5.1.0'
gem 'activerecord', '~> 5.1.0', require: 'active_record'
gem 'actionview', '~> 5.1.0', require: 'action_view'
+gem 'byebug'
platforms :ruby do
gem 'sqlite3', require: false
diff --git a/kaminari-core/app/views/kaminari/_paginator.html.erb b/kaminari-core/app/views/kaminari/_paginator.html.erb
index 5525f48..846ab02 100644
--- a/kaminari-core/app/views/kaminari/_paginator.html.erb
+++ b/kaminari-core/app/views/kaminari/_paginator.html.erb
@@ -6,20 +6,8 @@
remote: data-remote
paginator: the paginator that renders the pagination tags inside
-%>
-<%= paginator.render do -%>
-
-<% end -%>
+
diff --git a/kaminari-core/lib/kaminari/helpers/helper_methods.rb b/kaminari-core/lib/kaminari/helpers/helper_methods.rb
index cfd788c..8faa46f 100644
--- a/kaminari-core/lib/kaminari/helpers/helper_methods.rb
+++ b/kaminari-core/lib/kaminari/helpers/helper_methods.rb
@@ -22,8 +22,7 @@ module Kaminari
options[:total_pages] ||= scope.total_pages
options.reverse_merge! current_page: scope.current_page, per_page: scope.limit_value, remote: false
- paginator = paginator_class.new (template || self), options
- paginator.to_s
+ render paginator_class.new(router: Kaminari::Helpers::Tag.new((template || self), options), **options)
end
# A simple "Twitter like" pagination link that creates a link to the previous page.
diff --git a/kaminari-core/lib/kaminari/helpers/paginator.rb b/kaminari-core/lib/kaminari/helpers/paginator.rb
index f7c4cc0..fa4a6ae 100644
--- a/kaminari-core/lib/kaminari/helpers/paginator.rb
+++ b/kaminari-core/lib/kaminari/helpers/paginator.rb
@@ -5,32 +5,21 @@ require 'kaminari/helpers/tags'
module Kaminari
module Helpers
# The main container tag
- class Paginator < Tag
- def initialize(template, window: nil, outer_window: Kaminari.config.outer_window, left: Kaminari.config.left, right: Kaminari.config.right, inner_window: Kaminari.config.window, **options) #:nodoc:
+ class Paginator
+ def initialize(router: , window: nil, outer_window: Kaminari.config.outer_window, left: Kaminari.config.left, right: Kaminari.config.right, inner_window: Kaminari.config.window, **options) #:nodoc:
@window_options = {window: window || inner_window, left: left.zero? ? outer_window : left, right: right.zero? ? outer_window : right}
- @template, @options, @theme, @views_prefix, @last = template, options, options[:theme], options[:views_prefix], nil
+ @router, @options, @theme, @views_prefix, @last = router, options, options[:theme], options[:views_prefix], nil
@window_options.merge! @options
- @window_options[:current_page] = @options[:current_page] = PageProxy.new(@window_options, @options[:current_page], nil)
-
- #XXX Using parent template's buffer class for rendering each partial here. This might cause problems if the handler mismatches
- @output_buffer = if defined?(::ActionView::OutputBuffer)
- ::ActionView::OutputBuffer.new
- elsif template.instance_variable_get(:@output_buffer)
- template.instance_variable_get(:@output_buffer).class.new
- else
- ActiveSupport::SafeBuffer.new
- end
+ @window_options[:current_page] = @options[:current_page]
end
- # render given block as a view template
- def render(&block)
- instance_eval(&block) if @options[:total_pages] > 1
+ def page_url_for(page_tag)
+ @router.page_url_for(page_tag.page)
+ end
- # This allows for showing fall-back HTML when there's only one page:
- #
- # <%= paginate(@search_results) || "Showing all search results" %>
- @output_buffer.presence
+ def to_partial_path
+ [ @views_prefix, "kaminari", @theme, self.class.name.demodulize.underscore ].compact.join("/")
end
# enumerate each page providing PageProxy object as the block parameter
@@ -42,147 +31,72 @@ module Kaminari
def each_relevant_page
return to_enum(:each_relevant_page) unless block_given?
- relevant_pages(@window_options).each do |page|
- yield PageProxy.new(@window_options, page, @last)
- end
+ current_page, total_pages = @options[:current_page], @options[:total_pages]
+
+ [
+ FirstPage.new(page: 1, current: current_page, theme: @theme, views_prefix: @views_prefix),
+ PrevPage.new(page: current_page - 1, current: current_page, theme: @theme, views_prefix: @views_prefix),
+ relevant_pages.map { |page| Page.new(page: page, current: current_page, theme: @theme, views_prefix: @views_prefix) },
+ NextPage.new(page: current_page + 1, current: current_page, theme: @theme, views_prefix: @views_prefix),
+ LastPage.new(page: total_pages, current: current_page, theme: @theme, views_prefix: @views_prefix),
+ ].flatten.each {|page| yield page }
end
alias each_page each_relevant_page
- def relevant_pages(options)
+ def relevant_pages(options = @window_options)
left_window_plus_one = [*1..options[:left] + 1]
right_window_plus_one = [*options[:total_pages] - options[:right]..options[:total_pages]]
inside_window_plus_each_sides = [*options[:current_page] - options[:window] - 1..options[:current_page] + options[:window] + 1]
(left_window_plus_one | inside_window_plus_each_sides | right_window_plus_one).sort.reject {|x| (x < 1) || (x > options[:total_pages])}
end
- private :relevant_pages
- def page_tag(page)
- @last = Page.new @template, @options.merge(page: page)
- end
+ class Page
+ attr_reader :page, :current, :rel
- %w[first_page prev_page next_page last_page gap].each do |tag|
- eval <<-DEF, nil, __FILE__, __LINE__ + 1
- def #{tag}_tag
- @last = #{tag.classify}.new @template, @options
- end
- DEF
- end
-
- def to_s #:nodoc:
- Thread.current[:kaminari_rendering] = true
- super @window_options.merge paginator: self
- ensure
- Thread.current[:kaminari_rendering] = false
- end
-
- # delegates view helper methods to @template
- def method_missing(name, *args, &block)
- @template.respond_to?(name) ? @template.send(name, *args, &block) : super
- end
- private :method_missing
-
- # 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
+ def initialize(page: , current: false, theme: nil, views_prefix: nil)
+ @page = page
+ @current = current
+ @theme = theme
+ @views_prefix = views_prefix
end
- # the page number
- def number
- @page
- end
-
- # current page or not
def current?
- @page == @options[:current_page]
+ page == current
+ end
+
+ def current_page
+ PageProxy.new(page, current_page: current)
+ end
+
+ def to_partial_path
+ [ @views_prefix, "kaminari", @theme, self.class.name.demodulize.underscore ].compact.join("/")
+ end
+
+ def to_s
+ page.to_s
+ end
+ end
+
+ class FirstPage < Page; end
+ class PrevPage < Page; end
+ class NextPage < Page; end
+ class LastPage < Page; end
+
+ class PageProxy < SimpleDelegator
+ attr_reader :current_page
+
+ def initialize(page, current_page: )
+ super(page.to_i)
+ @current_page = current_page
end
- # the first page or not
def first?
- @page == 1
+ 1 == current_page
end
- # the last page or not
def last?
- @page == @options[:total_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
-
- # relationship with the current page
- def rel
- if next?
- 'next'
- elsif prev?
- 'prev'
- end
- 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[:total_pages] - @page < @options[:right]
- end
-
- # inside the inner window or not
- def inside_window?
- (@options[:current_page] - @page).abs <= @options[:window]
- end
-
- # Current page is an isolated gap or not
- def single_gap?
- ((@page == @options[:current_page] - @options[:window] - 1) && (@page == @options[:left] + 1)) ||
- ((@page == @options[:current_page] + @options[:window] + 1) && (@page == @options[:total_pages] - @options[:right]))
- end
-
- # The page number exceeds the range of pages or not
- def out_of_range?
- @page > @options[:total_pages]
- end
-
- # The last rendered tag was "truncated" or not
- def was_truncated?
- @last.is_a? Gap
- end
-
- #Should we display the link tag?
- def display_tag?
- left_outer? || right_outer? || inside_window? || single_gap?
- end
-
- def to_i #:nodoc:
- number
- end
-
- def to_s #:nodoc:
- number.to_s
- end
-
- def +(other) #:nodoc:
- to_i + other.to_i
- end
-
- def -(other) #:nodoc:
- to_i - other.to_i
- end
-
- def <=>(other) #:nodoc:
- to_i <=> other.to_i
+ __getobj__ == current_page
end
end
end
diff --git a/kaminari-core/lib/kaminari/helpers/tags.rb b/kaminari-core/lib/kaminari/helpers/tags.rb
index 3c4c440..7d8f6c7 100644
--- a/kaminari-core/lib/kaminari/helpers/tags.rb
+++ b/kaminari-core/lib/kaminari/helpers/tags.rb
@@ -27,11 +27,6 @@ module Kaminari
@params.merge! params
end
- def to_s(locals = {}) #:nodoc:
- formats = (@template.respond_to?(:formats) ? @template.formats : Array(@template.params[:format])) + [:html]
- @template.render partial: partial_path, locals: @options.merge(locals), formats: formats
- end
-
def page_url_for(page)
params = params_for(page)
params[:only_path] = true
@@ -58,60 +53,14 @@ module Kaminari
page_params
end
-
- def partial_path
- [
- @views_prefix,
- "kaminari",
- @theme,
- self.class.name.demodulize.underscore
- ].compact.join("/")
- end
end
# Tag that contains a link
module Link
- # target page number
- def page
- raise 'Override page with the actual page value to be a Page.'
- end
# the link's href
def url
page_url_for page
end
- def to_s(locals = {}) #:nodoc:
- locals[:url] = url
- super locals
- end
- end
-
- # A page
- class Page < Tag
- include Link
- # target page number
- def page
- @options[:page]
- end
- def to_s(locals = {}) #:nodoc:
- locals[:page] = page
- super locals
- end
- end
-
- # Link with page number that appears at the leftmost
- class FirstPage < Tag
- include Link
- def page #:nodoc:
- 1
- end
- end
-
- # Link with page number that appears at the rightmost
- class LastPage < Tag
- include Link
- def page #:nodoc:
- @options[:total_pages]
- end
end
# The "previous" page of the current page
diff --git a/kaminari-core/test/fake_app/rails_app.rb b/kaminari-core/test/fake_app/rails_app.rb
index 4999fdf..321ab66 100644
--- a/kaminari-core/test/fake_app/rails_app.rb
+++ b/kaminari-core/test/fake_app/rails_app.rb
@@ -10,6 +10,8 @@ class KaminariTestApp < Rails::Application
config.session_store :cookie_store, key: '_myapp_session'
config.active_support.deprecation = :log
config.eager_load = false
+ config.consider_all_requests_local = true
+ config.action_dispatch.show_exceptions = false
# Rails.root
config.root = File.dirname(__FILE__)
end