kaminari-core 1.0.0.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +21 -0
- data/README.md +31 -0
- data/app/views/kaminari/_first_page.html.erb +11 -0
- data/app/views/kaminari/_first_page.html.haml +9 -0
- data/app/views/kaminari/_first_page.html.slim +10 -0
- data/app/views/kaminari/_gap.html.erb +8 -0
- data/app/views/kaminari/_gap.html.haml +8 -0
- data/app/views/kaminari/_gap.html.slim +9 -0
- data/app/views/kaminari/_last_page.html.erb +11 -0
- data/app/views/kaminari/_last_page.html.haml +9 -0
- data/app/views/kaminari/_last_page.html.slim +10 -0
- data/app/views/kaminari/_next_page.html.erb +11 -0
- data/app/views/kaminari/_next_page.html.haml +9 -0
- data/app/views/kaminari/_next_page.html.slim +10 -0
- data/app/views/kaminari/_page.html.erb +12 -0
- data/app/views/kaminari/_page.html.haml +10 -0
- data/app/views/kaminari/_page.html.slim +11 -0
- data/app/views/kaminari/_paginator.html.erb +25 -0
- data/app/views/kaminari/_paginator.html.haml +18 -0
- data/app/views/kaminari/_paginator.html.slim +19 -0
- data/app/views/kaminari/_prev_page.html.erb +11 -0
- data/app/views/kaminari/_prev_page.html.haml +9 -0
- data/app/views/kaminari/_prev_page.html.slim +10 -0
- data/config/locales/kaminari.yml +23 -0
- data/kaminari-core.gemspec +23 -0
- data/lib/generators/kaminari/config_generator.rb +18 -0
- data/lib/generators/kaminari/templates/kaminari_config.rb +12 -0
- data/lib/generators/kaminari/views_generator.rb +134 -0
- data/lib/kaminari/config.rb +28 -0
- data/lib/kaminari/core.rb +23 -0
- data/lib/kaminari/core/version.rb +6 -0
- data/lib/kaminari/engine.rb +5 -0
- data/lib/kaminari/exceptions.rb +4 -0
- data/lib/kaminari/helpers/helper_methods.rb +169 -0
- data/lib/kaminari/helpers/paginator.rb +189 -0
- data/lib/kaminari/helpers/tags.rb +137 -0
- data/lib/kaminari/models/array_extension.rb +72 -0
- data/lib/kaminari/models/configuration_methods.rb +57 -0
- data/lib/kaminari/models/page_scope_methods.rb +80 -0
- data/lib/kaminari/railtie.rb +8 -0
- metadata +113 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_support/configurable'
|
3
|
+
|
4
|
+
module Kaminari
|
5
|
+
# Configures global settings for Kaminari
|
6
|
+
# Kaminari.configure do |config|
|
7
|
+
# config.default_per_page = 10
|
8
|
+
# end
|
9
|
+
include ActiveSupport::Configurable
|
10
|
+
|
11
|
+
config.instance_eval do
|
12
|
+
self.default_per_page = 25
|
13
|
+
self.max_per_page = nil
|
14
|
+
self.window = 4
|
15
|
+
self.outer_window = 0
|
16
|
+
self.left = 0
|
17
|
+
self.right = 0
|
18
|
+
self.page_method_name = :page
|
19
|
+
self.param_name = :page
|
20
|
+
self.max_pages = nil
|
21
|
+
self.params_on_first_page = false
|
22
|
+
|
23
|
+
# If param_name was given as a callable object, call it when returning
|
24
|
+
def param_name
|
25
|
+
self[:param_name].respond_to?(:call) ? self[:param_name].call : self[:param_name]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Kaminari
|
3
|
+
end
|
4
|
+
|
5
|
+
# load Rails/Railtie
|
6
|
+
begin
|
7
|
+
require 'rails'
|
8
|
+
rescue LoadError
|
9
|
+
#do nothing
|
10
|
+
end
|
11
|
+
|
12
|
+
# load Kaminari components
|
13
|
+
require 'kaminari/config'
|
14
|
+
require 'kaminari/exceptions'
|
15
|
+
require 'kaminari/helpers/paginator'
|
16
|
+
require 'kaminari/models/page_scope_methods'
|
17
|
+
require 'kaminari/models/configuration_methods'
|
18
|
+
require 'kaminari/models/array_extension'
|
19
|
+
|
20
|
+
if defined? ::Rails::Railtie
|
21
|
+
require 'kaminari/railtie'
|
22
|
+
require 'kaminari/engine'
|
23
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module Kaminari
|
2
|
+
module Helpers
|
3
|
+
module HelperMethods
|
4
|
+
# A helper that renders the pagination links.
|
5
|
+
#
|
6
|
+
# <%= paginate @articles %>
|
7
|
+
#
|
8
|
+
# ==== Options
|
9
|
+
# * <tt>:window</tt> - The "inner window" size (4 by default).
|
10
|
+
# * <tt>:outer_window</tt> - The "outer window" size (0 by default).
|
11
|
+
# * <tt>:left</tt> - The "left outer window" size (0 by default).
|
12
|
+
# * <tt>:right</tt> - The "right outer window" size (0 by default).
|
13
|
+
# * <tt>:params</tt> - url_for parameters for the links (:controller, :action, etc.)
|
14
|
+
# * <tt>:param_name</tt> - parameter name for page number in the links (:page by default)
|
15
|
+
# * <tt>:remote</tt> - Ajax? (false by default)
|
16
|
+
# * <tt>:paginator_class</tt> - Specify a custom Paginator (Kaminari::Helpers::Paginator by default)
|
17
|
+
# * <tt>:template</tt> - Specify a custom template renderer for rendering the Paginator (receiver by default)
|
18
|
+
# * <tt>:ANY_OTHER_VALUES</tt> - Any other hash key & values would be directly passed into each tag as :locals value.
|
19
|
+
def paginate(scope, paginator_class: Kaminari::Helpers::Paginator, template: nil, **options)
|
20
|
+
options[:total_pages] ||= scope.total_pages
|
21
|
+
options.reverse_merge! current_page: scope.current_page, per_page: scope.limit_value, remote: false
|
22
|
+
|
23
|
+
paginator = paginator_class.new (template || self), options
|
24
|
+
paginator.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
# A simple "Twitter like" pagination link that creates a link to the previous page.
|
28
|
+
#
|
29
|
+
# ==== Examples
|
30
|
+
# Basic usage:
|
31
|
+
#
|
32
|
+
# <%= link_to_previous_page @items, 'Previous Page' %>
|
33
|
+
#
|
34
|
+
# Ajax:
|
35
|
+
#
|
36
|
+
# <%= link_to_previous_page @items, 'Previous Page', remote: true %>
|
37
|
+
#
|
38
|
+
# By default, it renders nothing if there are no more results on the previous page.
|
39
|
+
# You can customize this output by passing a block.
|
40
|
+
#
|
41
|
+
# <%= link_to_previous_page @users, 'Previous Page' do %>
|
42
|
+
# <span>At the Beginning</span>
|
43
|
+
# <% end %>
|
44
|
+
def link_to_previous_page(scope, name, **options)
|
45
|
+
prev_page = path_to_prev_page(scope, options)
|
46
|
+
|
47
|
+
options.except! :params, :param_name
|
48
|
+
options[:rel] ||= 'prev'
|
49
|
+
|
50
|
+
link_to_if prev_page, name, prev_page, options do
|
51
|
+
yield if block_given?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
alias link_to_prev_page link_to_previous_page
|
55
|
+
|
56
|
+
# A simple "Twitter like" pagination link that creates a link to the next page.
|
57
|
+
#
|
58
|
+
# ==== Examples
|
59
|
+
# Basic usage:
|
60
|
+
#
|
61
|
+
# <%= link_to_next_page @items, 'Next Page' %>
|
62
|
+
#
|
63
|
+
# Ajax:
|
64
|
+
#
|
65
|
+
# <%= link_to_next_page @items, 'Next Page', remote: true %>
|
66
|
+
#
|
67
|
+
# By default, it renders nothing if there are no more results on the next page.
|
68
|
+
# You can customize this output by passing a block.
|
69
|
+
#
|
70
|
+
# <%= link_to_next_page @users, 'Next Page' do %>
|
71
|
+
# <span>No More Pages</span>
|
72
|
+
# <% end %>
|
73
|
+
def link_to_next_page(scope, name, **options)
|
74
|
+
next_page = path_to_next_page(scope, options)
|
75
|
+
|
76
|
+
options.except! :params, :param_name
|
77
|
+
options[:rel] ||= 'next'
|
78
|
+
|
79
|
+
link_to_if next_page, name, next_page, options do
|
80
|
+
yield if block_given?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Renders a helpful message with numbers of displayed vs. total entries.
|
85
|
+
# Ported from mislav/will_paginate
|
86
|
+
#
|
87
|
+
# ==== Examples
|
88
|
+
# Basic usage:
|
89
|
+
#
|
90
|
+
# <%= page_entries_info @posts %>
|
91
|
+
# #-> Displaying posts 6 - 10 of 26 in total
|
92
|
+
#
|
93
|
+
# By default, the message will use the humanized class name of objects
|
94
|
+
# in collection: for instance, "project types" for ProjectType models.
|
95
|
+
# The namespace will be cutted out and only the last name will be used.
|
96
|
+
# Override this with the <tt>:entry_name</tt> parameter:
|
97
|
+
#
|
98
|
+
# <%= page_entries_info @posts, entry_name: 'item' %>
|
99
|
+
# #-> Displaying items 6 - 10 of 26 in total
|
100
|
+
def page_entries_info(collection, entry_name: nil)
|
101
|
+
entry_name = if entry_name
|
102
|
+
entry_name.pluralize(collection.size)
|
103
|
+
else
|
104
|
+
collection.entry_name(count: collection.size).downcase
|
105
|
+
end
|
106
|
+
|
107
|
+
if collection.total_pages < 2
|
108
|
+
t('helpers.page_entries_info.one_page.display_entries', entry_name: entry_name, count: collection.total_count)
|
109
|
+
else
|
110
|
+
t('helpers.page_entries_info.more_pages.display_entries', entry_name: entry_name, first: collection.offset_value + 1, last: [collection.offset_value + collection.limit_value, collection.total_count].min, total: collection.total_count)
|
111
|
+
end.html_safe
|
112
|
+
end
|
113
|
+
|
114
|
+
# Renders rel="next" and rel="prev" links to be used in the head.
|
115
|
+
#
|
116
|
+
# ==== Examples
|
117
|
+
# Basic usage:
|
118
|
+
#
|
119
|
+
# In head:
|
120
|
+
# <head>
|
121
|
+
# <title>My Website</title>
|
122
|
+
# <%= yield :head %>
|
123
|
+
# </head>
|
124
|
+
#
|
125
|
+
# Somewhere in body:
|
126
|
+
# <% content_for :head do %>
|
127
|
+
# <%= rel_next_prev_link_tags @items %>
|
128
|
+
# <% end %>
|
129
|
+
#
|
130
|
+
# #-> <link rel="next" href="/items/page/3" /><link rel="prev" href="/items/page/1" />
|
131
|
+
#
|
132
|
+
def rel_next_prev_link_tags(scope, options = {})
|
133
|
+
next_page = path_to_next_page(scope, options)
|
134
|
+
prev_page = path_to_prev_page(scope, options)
|
135
|
+
|
136
|
+
output = String.new
|
137
|
+
output << tag(:link, rel: "next", href: next_page) if next_page
|
138
|
+
output << tag(:link, rel: "prev", href: prev_page) if prev_page
|
139
|
+
output.html_safe
|
140
|
+
end
|
141
|
+
|
142
|
+
# A helper that calculates the path to the next page.
|
143
|
+
#
|
144
|
+
# ==== Examples
|
145
|
+
# Basic usage:
|
146
|
+
#
|
147
|
+
# <%= path_to_next_page @items %>
|
148
|
+
# #-> /items?page=2
|
149
|
+
#
|
150
|
+
# It will return `nil` if there is no next page.
|
151
|
+
def path_to_next_page(scope, options = {})
|
152
|
+
Kaminari::Helpers::NextPage.new(self, options.reverse_merge(current_page: scope.current_page)).url if scope.next_page
|
153
|
+
end
|
154
|
+
|
155
|
+
# A helper that calculates the path to the previous page.
|
156
|
+
#
|
157
|
+
# ==== Examples
|
158
|
+
# Basic usage:
|
159
|
+
#
|
160
|
+
# <%= path_to_prev_page @items %>
|
161
|
+
# #-> /items
|
162
|
+
#
|
163
|
+
# It will return `nil` if there is no previous page.
|
164
|
+
def path_to_prev_page(scope, options = {})
|
165
|
+
Kaminari::Helpers::PrevPage.new(self, options.reverse_merge(current_page: scope.current_page)).url if scope.prev_page
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_support/inflector'
|
3
|
+
require 'kaminari/helpers/tags'
|
4
|
+
|
5
|
+
module Kaminari
|
6
|
+
module Helpers
|
7
|
+
# The main container tag
|
8
|
+
class Paginator < Tag
|
9
|
+
def initialize(template, window: nil, outer_window: nil, left: nil, right: nil, inner_window: nil, **options) #:nodoc:
|
10
|
+
outer_window ||= Kaminari.config.outer_window
|
11
|
+
left ||= Kaminari.config.left
|
12
|
+
right ||= Kaminari.config.right
|
13
|
+
@window_options = {window: window || inner_window || Kaminari.config.window, left: left.zero? ? outer_window : left, right: right.zero? ? outer_window : right}
|
14
|
+
|
15
|
+
@template, @options, @theme, @views_prefix, @last = template, options, options[:theme], options[:views_prefix], nil
|
16
|
+
@window_options.merge! @options
|
17
|
+
@window_options[:current_page] = @options[:current_page] = PageProxy.new(@window_options, @options[:current_page], nil)
|
18
|
+
|
19
|
+
#XXX Using parent template's buffer class for rendering each partial here. This might cause problems if the handler mismatches
|
20
|
+
@output_buffer = if defined?(::ActionView::OutputBuffer)
|
21
|
+
::ActionView::OutputBuffer.new
|
22
|
+
elsif template.instance_variable_get(:@output_buffer)
|
23
|
+
template.instance_variable_get(:@output_buffer).class.new
|
24
|
+
else
|
25
|
+
ActiveSupport::SafeBuffer.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# render given block as a view template
|
30
|
+
def render(&block)
|
31
|
+
instance_eval(&block) if @options[:total_pages] > 1
|
32
|
+
@output_buffer
|
33
|
+
end
|
34
|
+
|
35
|
+
# enumerate each page providing PageProxy object as the block parameter
|
36
|
+
# Because of performance reason, this doesn't actually enumerate all pages but pages that are seemingly relevant to the paginator.
|
37
|
+
# "Relevant" pages are:
|
38
|
+
# * pages inside the left outer window plus one for showing the gap tag
|
39
|
+
# * pages inside the inner window plus one on the left plus one on the right for showing the gap tags
|
40
|
+
# * pages inside the right outer window plus one for showing the gap tag
|
41
|
+
def each_relevant_page
|
42
|
+
return to_enum(:each_relevant_page) unless block_given?
|
43
|
+
|
44
|
+
relevant_pages(@window_options).each do |page|
|
45
|
+
yield PageProxy.new(@window_options, page, @last)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
alias each_page each_relevant_page
|
49
|
+
|
50
|
+
def relevant_pages(options)
|
51
|
+
left_window_plus_one = [*1..options[:left] + 1]
|
52
|
+
right_window_plus_one = [*options[:total_pages] - options[:right]..options[:total_pages]]
|
53
|
+
inside_window_plus_each_sides = [*options[:current_page] - options[:window] - 1..options[:current_page] + options[:window] + 1]
|
54
|
+
|
55
|
+
(left_window_plus_one | inside_window_plus_each_sides | right_window_plus_one).sort.reject {|x| (x < 1) || (x > options[:total_pages])}
|
56
|
+
end
|
57
|
+
private :relevant_pages
|
58
|
+
|
59
|
+
def page_tag(page)
|
60
|
+
@last = Page.new @template, @options.merge(page: page)
|
61
|
+
end
|
62
|
+
|
63
|
+
%w[first_page prev_page next_page last_page gap].each do |tag|
|
64
|
+
eval <<-DEF, nil, __FILE__, __LINE__ + 1
|
65
|
+
def #{tag}_tag
|
66
|
+
@last = #{tag.classify}.new @template, @options
|
67
|
+
end
|
68
|
+
DEF
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s #:nodoc:
|
72
|
+
Thread.current[:kaminari_rendering] = true
|
73
|
+
super @window_options.merge paginator: self
|
74
|
+
ensure
|
75
|
+
Thread.current[:kaminari_rendering] = false
|
76
|
+
end
|
77
|
+
|
78
|
+
# delegates view helper methods to @template
|
79
|
+
def method_missing(name, *args, &block)
|
80
|
+
@template.respond_to?(name) ? @template.send(name, *args, &block) : super
|
81
|
+
end
|
82
|
+
private :method_missing
|
83
|
+
|
84
|
+
# Wraps a "page number" and provides some utility methods
|
85
|
+
class PageProxy
|
86
|
+
include Comparable
|
87
|
+
|
88
|
+
def initialize(options, page, last) #:nodoc:
|
89
|
+
@options, @page, @last = options, page, last
|
90
|
+
end
|
91
|
+
|
92
|
+
# the page number
|
93
|
+
def number
|
94
|
+
@page
|
95
|
+
end
|
96
|
+
|
97
|
+
# current page or not
|
98
|
+
def current?
|
99
|
+
@page == @options[:current_page]
|
100
|
+
end
|
101
|
+
|
102
|
+
# the first page or not
|
103
|
+
def first?
|
104
|
+
@page == 1
|
105
|
+
end
|
106
|
+
|
107
|
+
# the last page or not
|
108
|
+
def last?
|
109
|
+
@page == @options[:total_pages]
|
110
|
+
end
|
111
|
+
|
112
|
+
# the previous page or not
|
113
|
+
def prev?
|
114
|
+
@page == @options[:current_page] - 1
|
115
|
+
end
|
116
|
+
|
117
|
+
# the next page or not
|
118
|
+
def next?
|
119
|
+
@page == @options[:current_page] + 1
|
120
|
+
end
|
121
|
+
|
122
|
+
# relationship with the current page
|
123
|
+
def rel
|
124
|
+
if next?
|
125
|
+
'next'
|
126
|
+
elsif prev?
|
127
|
+
'prev'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# within the left outer window or not
|
132
|
+
def left_outer?
|
133
|
+
@page <= @options[:left]
|
134
|
+
end
|
135
|
+
|
136
|
+
# within the right outer window or not
|
137
|
+
def right_outer?
|
138
|
+
@options[:total_pages] - @page < @options[:right]
|
139
|
+
end
|
140
|
+
|
141
|
+
# inside the inner window or not
|
142
|
+
def inside_window?
|
143
|
+
(@options[:current_page] - @page).abs <= @options[:window]
|
144
|
+
end
|
145
|
+
|
146
|
+
# Current page is an isolated gap or not
|
147
|
+
def single_gap?
|
148
|
+
((@page == @options[:current_page] - @options[:window] - 1) && (@page == @options[:left] + 1)) ||
|
149
|
+
((@page == @options[:current_page] + @options[:window] + 1) && (@page == @options[:total_pages] - @options[:right]))
|
150
|
+
end
|
151
|
+
|
152
|
+
# The page number exceeds the range of pages or not
|
153
|
+
def out_of_range?
|
154
|
+
@page > @options[:total_pages]
|
155
|
+
end
|
156
|
+
|
157
|
+
# The last rendered tag was "truncated" or not
|
158
|
+
def was_truncated?
|
159
|
+
@last.is_a? Gap
|
160
|
+
end
|
161
|
+
|
162
|
+
#Should we display the link tag?
|
163
|
+
def display_tag?
|
164
|
+
left_outer? || right_outer? || inside_window? || single_gap?
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_i #:nodoc:
|
168
|
+
number
|
169
|
+
end
|
170
|
+
|
171
|
+
def to_s #:nodoc:
|
172
|
+
number.to_s
|
173
|
+
end
|
174
|
+
|
175
|
+
def +(other) #:nodoc:
|
176
|
+
to_i + other.to_i
|
177
|
+
end
|
178
|
+
|
179
|
+
def -(other) #:nodoc:
|
180
|
+
to_i - other.to_i
|
181
|
+
end
|
182
|
+
|
183
|
+
def <=>(other) #:nodoc:
|
184
|
+
to_i <=> other.to_i
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Kaminari
|
3
|
+
module Helpers
|
4
|
+
PARAM_KEY_BLACKLIST = [:authenticity_token, :commit, :utf8, :_method, :script_name].freeze
|
5
|
+
|
6
|
+
# A tag stands for an HTML tag inside the paginator.
|
7
|
+
# Basically, a tag has its own partial template file, so every tag can be
|
8
|
+
# rendered into String using its partial template.
|
9
|
+
#
|
10
|
+
# The template file should be placed in your app/views/kaminari/ directory
|
11
|
+
# with underscored class name (besides the "Tag" class. Tag is an abstract
|
12
|
+
# class, so _tag partial is not needed).
|
13
|
+
# e.g.) PrevLink -> app/views/kaminari/_prev_link.html.erb
|
14
|
+
#
|
15
|
+
# When no matching template were found in your app, the engine's pre
|
16
|
+
# installed template will be used.
|
17
|
+
# e.g.) Paginator -> $GEM_HOME/kaminari-x.x.x/app/views/kaminari/_paginator.html.erb
|
18
|
+
class Tag
|
19
|
+
def initialize(template, params: {}, param_name: nil, theme: nil, views_prefix: nil, **options) #:nodoc:
|
20
|
+
@template, @theme, @views_prefix, @options = template, theme, views_prefix, options
|
21
|
+
@param_name = param_name || Kaminari.config.param_name
|
22
|
+
@params = template.params
|
23
|
+
# @params in Rails 5 no longer inherits from Hash
|
24
|
+
@params = @params.to_unsafe_h if @params.respond_to?(:to_unsafe_h)
|
25
|
+
@params = @params.with_indifferent_access
|
26
|
+
@params.except!(*PARAM_KEY_BLACKLIST)
|
27
|
+
@params.merge! params
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s(locals = {}) #:nodoc:
|
31
|
+
formats = (@template.respond_to?(:formats) ? @template.formats : Array(@template.params[:format])) + [:html]
|
32
|
+
@template.render partial: partial_path, locals: @options.merge(locals), formats: formats
|
33
|
+
end
|
34
|
+
|
35
|
+
def page_url_for(page)
|
36
|
+
params = params_for(page)
|
37
|
+
params[:only_path] = true
|
38
|
+
@template.url_for params
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def params_for(page)
|
44
|
+
page_params = Rack::Utils.parse_nested_query("#{@param_name}=#{page}")
|
45
|
+
page_params = @params.deep_merge(page_params)
|
46
|
+
|
47
|
+
if !Kaminari.config.params_on_first_page && (page <= 1)
|
48
|
+
# This converts a hash:
|
49
|
+
# from: {other: "params", page: 1}
|
50
|
+
# to: {other: "params", page: nil}
|
51
|
+
# (when @param_name == "page")
|
52
|
+
#
|
53
|
+
# from: {other: "params", user: {name: "yuki", page: 1}}
|
54
|
+
# to: {other: "params", user: {name: "yuki", page: nil}}
|
55
|
+
# (when @param_name == "user[page]")
|
56
|
+
@param_name.to_s.scan(/[\w\.]+/)[0..-2].inject(page_params){|h, k| h[k] }[$&] = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
page_params
|
60
|
+
end
|
61
|
+
|
62
|
+
def partial_path
|
63
|
+
[
|
64
|
+
@views_prefix,
|
65
|
+
"kaminari",
|
66
|
+
@theme,
|
67
|
+
self.class.name.demodulize.underscore
|
68
|
+
].compact.join("/")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Tag that contains a link
|
73
|
+
module Link
|
74
|
+
# target page number
|
75
|
+
def page
|
76
|
+
raise 'Override page with the actual page value to be a Page.'
|
77
|
+
end
|
78
|
+
# the link's href
|
79
|
+
def url
|
80
|
+
page_url_for page
|
81
|
+
end
|
82
|
+
def to_s(locals = {}) #:nodoc:
|
83
|
+
locals[:url] = url
|
84
|
+
super locals
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# A page
|
89
|
+
class Page < Tag
|
90
|
+
include Link
|
91
|
+
# target page number
|
92
|
+
def page
|
93
|
+
@options[:page]
|
94
|
+
end
|
95
|
+
def to_s(locals = {}) #:nodoc:
|
96
|
+
locals[:page] = page
|
97
|
+
super locals
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Link with page number that appears at the leftmost
|
102
|
+
class FirstPage < Tag
|
103
|
+
include Link
|
104
|
+
def page #:nodoc:
|
105
|
+
1
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Link with page number that appears at the rightmost
|
110
|
+
class LastPage < Tag
|
111
|
+
include Link
|
112
|
+
def page #:nodoc:
|
113
|
+
@options[:total_pages]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# The "previous" page of the current page
|
118
|
+
class PrevPage < Tag
|
119
|
+
include Link
|
120
|
+
def page #:nodoc:
|
121
|
+
@options[:current_page] - 1
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# The "next" page of the current page
|
126
|
+
class NextPage < Tag
|
127
|
+
include Link
|
128
|
+
def page #:nodoc:
|
129
|
+
@options[:current_page] + 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Non-link tag that stands for skipped pages...
|
134
|
+
class Gap < Tag
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|