nano-pure-mod 0.0.1
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/nano-pure-mod.gemspec +12 -0
- data/will_paginate-4.0.1/LICENSE +18 -0
- data/will_paginate-4.0.1/README.md +58 -0
- data/will_paginate-4.0.1/lib/will_paginate/active_record.rb +248 -0
- data/will_paginate-4.0.1/lib/will_paginate/array.rb +33 -0
- data/will_paginate-4.0.1/lib/will_paginate/collection.rb +136 -0
- data/will_paginate-4.0.1/lib/will_paginate/core_ext.rb +30 -0
- data/will_paginate-4.0.1/lib/will_paginate/deprecation.rb +55 -0
- data/will_paginate-4.0.1/lib/will_paginate/i18n.rb +22 -0
- data/will_paginate-4.0.1/lib/will_paginate/locale/en.yml +37 -0
- data/will_paginate-4.0.1/lib/will_paginate/mongoid.rb +48 -0
- data/will_paginate-4.0.1/lib/will_paginate/page_number.rb +53 -0
- data/will_paginate-4.0.1/lib/will_paginate/per_page.rb +27 -0
- data/will_paginate-4.0.1/lib/will_paginate/railtie.rb +74 -0
- data/will_paginate-4.0.1/lib/will_paginate/sequel.rb +39 -0
- data/will_paginate-4.0.1/lib/will_paginate/version.rb +9 -0
- data/will_paginate-4.0.1/lib/will_paginate/view_helpers/action_view.rb +155 -0
- data/will_paginate-4.0.1/lib/will_paginate/view_helpers/hanami.rb +41 -0
- data/will_paginate-4.0.1/lib/will_paginate/view_helpers/link_renderer.rb +136 -0
- data/will_paginate-4.0.1/lib/will_paginate/view_helpers/link_renderer_base.rb +77 -0
- data/will_paginate-4.0.1/lib/will_paginate/view_helpers/sinatra.rb +41 -0
- data/will_paginate-4.0.1/lib/will_paginate/view_helpers.rb +162 -0
- data/will_paginate-4.0.1/lib/will_paginate.rb +13 -0
- metadata +64 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'mongoid'
|
|
2
|
+
require 'will_paginate/collection'
|
|
3
|
+
|
|
4
|
+
module WillPaginate
|
|
5
|
+
module Mongoid
|
|
6
|
+
module CriteriaMethods
|
|
7
|
+
def paginate(options = {})
|
|
8
|
+
extend CollectionMethods
|
|
9
|
+
@current_page = WillPaginate::PageNumber(options[:page] || @current_page || 1)
|
|
10
|
+
@page_multiplier = current_page - 1
|
|
11
|
+
@total_entries = options.delete(:total_entries)
|
|
12
|
+
|
|
13
|
+
pp = (options[:per_page] || per_page || WillPaginate.per_page).to_i
|
|
14
|
+
limit(pp).skip(@page_multiplier * pp)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def per_page(value = :non_given)
|
|
18
|
+
if value == :non_given
|
|
19
|
+
options[:limit] == 0 ? nil : options[:limit] # in new Mongoid versions a nil limit is saved as 0
|
|
20
|
+
else
|
|
21
|
+
limit(value)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def page(page)
|
|
26
|
+
paginate(:page => page)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module CollectionMethods
|
|
31
|
+
attr_reader :current_page
|
|
32
|
+
|
|
33
|
+
def total_entries
|
|
34
|
+
@total_entries ||= count
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def total_pages
|
|
38
|
+
(total_entries / per_page.to_f).ceil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def offset
|
|
42
|
+
@page_multiplier * per_page
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
::Mongoid::Criteria.send(:include, CriteriaMethods)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
|
|
3
|
+
module WillPaginate
|
|
4
|
+
# a module that page number exceptions are tagged with
|
|
5
|
+
module InvalidPage; end
|
|
6
|
+
|
|
7
|
+
# integer representing a page number
|
|
8
|
+
class PageNumber < Numeric
|
|
9
|
+
# a value larger than this is not supported in SQL queries
|
|
10
|
+
BIGINT = 9223372036854775807
|
|
11
|
+
|
|
12
|
+
extend Forwardable
|
|
13
|
+
|
|
14
|
+
def initialize(value, name)
|
|
15
|
+
value = Integer(value)
|
|
16
|
+
if 'offset' == name ? (value < 0 or value > BIGINT) : value < 1
|
|
17
|
+
raise RangeError, "invalid #{name}: #{value.inspect}"
|
|
18
|
+
end
|
|
19
|
+
@name = name
|
|
20
|
+
@value = value
|
|
21
|
+
rescue ArgumentError, TypeError, RangeError => error
|
|
22
|
+
error.extend InvalidPage
|
|
23
|
+
raise error
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_i
|
|
27
|
+
@value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def_delegators :@value, :coerce, :==, :<=>, :to_s, :+, :-, :*, :/, :to_json
|
|
31
|
+
|
|
32
|
+
def inspect
|
|
33
|
+
"#{@name} #{to_i}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def to_offset(per_page)
|
|
37
|
+
PageNumber.new((to_i - 1) * per_page.to_i, 'offset')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def kind_of?(klass)
|
|
41
|
+
super || to_i.kind_of?(klass)
|
|
42
|
+
end
|
|
43
|
+
alias is_a? kind_of?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# An idemptotent coercion method
|
|
47
|
+
def self.PageNumber(value, name = 'page')
|
|
48
|
+
case value
|
|
49
|
+
when PageNumber then value
|
|
50
|
+
else PageNumber.new(value, name)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module WillPaginate
|
|
2
|
+
module PerPage
|
|
3
|
+
def per_page
|
|
4
|
+
defined?(@per_page) ? @per_page : WillPaginate.per_page
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def per_page=(limit)
|
|
8
|
+
@per_page = limit.to_i
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.extended(base)
|
|
12
|
+
base.extend Inheritance if base.is_a? Class
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Inheritance
|
|
16
|
+
def inherited(subclass)
|
|
17
|
+
super
|
|
18
|
+
subclass.per_page = self.per_page
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
extend PerPage
|
|
24
|
+
|
|
25
|
+
# default number of items per page
|
|
26
|
+
self.per_page = 30
|
|
27
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'will_paginate/page_number'
|
|
2
|
+
require 'will_paginate/collection'
|
|
3
|
+
require 'will_paginate/i18n'
|
|
4
|
+
|
|
5
|
+
module WillPaginate
|
|
6
|
+
class Railtie < Rails::Railtie
|
|
7
|
+
initializer "will_paginate" do |app|
|
|
8
|
+
ActiveSupport.on_load :active_record do
|
|
9
|
+
require 'will_paginate/active_record'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
ActiveSupport.on_load :action_controller do
|
|
13
|
+
WillPaginate::Railtie.setup_actioncontroller
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ActiveSupport.on_load :action_view do
|
|
17
|
+
require 'will_paginate/view_helpers/action_view'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# early access to ViewHelpers.pagination_options
|
|
21
|
+
require 'will_paginate/view_helpers'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.setup_actioncontroller
|
|
25
|
+
( defined?(ActionDispatch::ExceptionWrapper) ?
|
|
26
|
+
ActionDispatch::ExceptionWrapper : ActionDispatch::ShowExceptions
|
|
27
|
+
).send :include, ShowExceptionsPatch
|
|
28
|
+
ActionController::Base.extend ControllerRescuePatch
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Extending the exception handler middleware so it properly detects
|
|
32
|
+
# WillPaginate::InvalidPage regardless of it being a tag module.
|
|
33
|
+
module ShowExceptionsPatch
|
|
34
|
+
extend ActiveSupport::Concern
|
|
35
|
+
included do
|
|
36
|
+
alias_method :status_code_without_paginate, :status_code
|
|
37
|
+
alias_method :status_code, :status_code_with_paginate
|
|
38
|
+
end
|
|
39
|
+
def status_code_with_paginate(exception = @exception)
|
|
40
|
+
actual_exception = if exception.respond_to?(:cause)
|
|
41
|
+
exception.cause || exception
|
|
42
|
+
elsif exception.respond_to?(:original_exception)
|
|
43
|
+
exception.original_exception
|
|
44
|
+
else
|
|
45
|
+
exception
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if actual_exception.is_a?(WillPaginate::InvalidPage)
|
|
49
|
+
Rack::Utils.status_code(:not_found)
|
|
50
|
+
else
|
|
51
|
+
original_method = method(:status_code_without_paginate)
|
|
52
|
+
if original_method.arity != 0
|
|
53
|
+
original_method.call(exception)
|
|
54
|
+
else
|
|
55
|
+
original_method.call()
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
module ControllerRescuePatch
|
|
62
|
+
def rescue_from(*args, **kwargs, &block)
|
|
63
|
+
if idx = args.index(WillPaginate::InvalidPage)
|
|
64
|
+
args[idx] = args[idx].name
|
|
65
|
+
end
|
|
66
|
+
super(*args, **kwargs, &block)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
ActiveSupport.on_load :i18n do
|
|
73
|
+
I18n.load_path.concat(WillPaginate::I18n.load_path)
|
|
74
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'sequel'
|
|
2
|
+
require 'sequel/extensions/pagination'
|
|
3
|
+
require 'will_paginate/collection'
|
|
4
|
+
|
|
5
|
+
module WillPaginate
|
|
6
|
+
# Sequel already supports pagination; we only need to make the
|
|
7
|
+
# resulting dataset look a bit more like WillPaginate::Collection
|
|
8
|
+
module SequelMethods
|
|
9
|
+
include WillPaginate::CollectionMethods
|
|
10
|
+
|
|
11
|
+
def total_pages
|
|
12
|
+
page_count
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def per_page
|
|
16
|
+
page_size
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def size
|
|
20
|
+
current_page_record_count
|
|
21
|
+
end
|
|
22
|
+
alias length size
|
|
23
|
+
|
|
24
|
+
def total_entries
|
|
25
|
+
pagination_record_count
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def out_of_bounds?
|
|
29
|
+
current_page > total_pages
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Current offset of the paginated collection
|
|
33
|
+
def offset
|
|
34
|
+
(current_page - 1) * per_page
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
Sequel::Dataset::Pagination.send(:include, SequelMethods)
|
|
39
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
require 'will_paginate/view_helpers'
|
|
2
|
+
require 'will_paginate/view_helpers/link_renderer'
|
|
3
|
+
|
|
4
|
+
module WillPaginate
|
|
5
|
+
# = ActionView helpers
|
|
6
|
+
#
|
|
7
|
+
# This module serves for availability in ActionView templates. It also adds a new
|
|
8
|
+
# view helper: +paginated_section+.
|
|
9
|
+
#
|
|
10
|
+
# == Using the helper without arguments
|
|
11
|
+
# If the helper is called without passing in the collection object, it will
|
|
12
|
+
# try to read from the instance variable inferred by the controller name.
|
|
13
|
+
# For example, calling +will_paginate+ while the current controller is
|
|
14
|
+
# PostsController will result in trying to read from the <tt>@posts</tt>
|
|
15
|
+
# variable. Example:
|
|
16
|
+
#
|
|
17
|
+
# <%= will_paginate :id => true %>
|
|
18
|
+
#
|
|
19
|
+
# ... will result in <tt>@post</tt> collection getting paginated:
|
|
20
|
+
#
|
|
21
|
+
# <div class="pagination" id="posts_pagination"> ... </div>
|
|
22
|
+
#
|
|
23
|
+
module ActionView
|
|
24
|
+
include ViewHelpers
|
|
25
|
+
|
|
26
|
+
def will_paginate(collection = nil, options = {}) #:nodoc:
|
|
27
|
+
options, collection = collection, nil if collection.is_a? Hash
|
|
28
|
+
collection ||= infer_collection_from_controller
|
|
29
|
+
|
|
30
|
+
options = options.symbolize_keys
|
|
31
|
+
options[:renderer] ||= LinkRenderer
|
|
32
|
+
|
|
33
|
+
super(collection, options)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def page_entries_info(collection = nil, options = {}) #:nodoc:
|
|
37
|
+
options, collection = collection, nil if collection.is_a? Hash
|
|
38
|
+
collection ||= infer_collection_from_controller
|
|
39
|
+
|
|
40
|
+
super(collection, options.symbolize_keys)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Wrapper for rendering pagination links at both top and bottom of a block
|
|
44
|
+
# of content.
|
|
45
|
+
#
|
|
46
|
+
# <%= paginated_section @posts do %>
|
|
47
|
+
# <ol id="posts">
|
|
48
|
+
# <% for post in @posts %>
|
|
49
|
+
# <li> ... </li>
|
|
50
|
+
# <% end %>
|
|
51
|
+
# </ol>
|
|
52
|
+
# <% end %>
|
|
53
|
+
#
|
|
54
|
+
# will result in:
|
|
55
|
+
#
|
|
56
|
+
# <div class="pagination"> ... </div>
|
|
57
|
+
# <ol id="posts">
|
|
58
|
+
# ...
|
|
59
|
+
# </ol>
|
|
60
|
+
# <div class="pagination"> ... </div>
|
|
61
|
+
#
|
|
62
|
+
# Arguments are passed to a <tt>will_paginate</tt> call, so the same options
|
|
63
|
+
# apply. Don't use the <tt>:id</tt> option; otherwise you'll finish with two
|
|
64
|
+
# blocks of pagination links sharing the same ID (which is invalid HTML).
|
|
65
|
+
def paginated_section(*args, &block)
|
|
66
|
+
pagination = will_paginate(*args)
|
|
67
|
+
if pagination
|
|
68
|
+
pagination + capture(&block) + pagination
|
|
69
|
+
else
|
|
70
|
+
capture(&block)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def will_paginate_translate(keys, options = {})
|
|
75
|
+
if respond_to? :translate
|
|
76
|
+
if Array === keys
|
|
77
|
+
defaults = keys.dup
|
|
78
|
+
key = defaults.shift
|
|
79
|
+
else
|
|
80
|
+
defaults = nil
|
|
81
|
+
key = keys
|
|
82
|
+
end
|
|
83
|
+
translate(key, **options.merge(:default => defaults, :scope => :will_paginate))
|
|
84
|
+
else
|
|
85
|
+
super
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
protected
|
|
90
|
+
|
|
91
|
+
def infer_collection_from_controller
|
|
92
|
+
collection_name = "@#{controller.controller_name}"
|
|
93
|
+
collection = instance_variable_get(collection_name)
|
|
94
|
+
raise ArgumentError, "The #{collection_name} variable appears to be empty. Did you " +
|
|
95
|
+
"forget to pass the collection object for will_paginate?" if collection.nil?
|
|
96
|
+
collection
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class LinkRenderer < ViewHelpers::LinkRenderer
|
|
100
|
+
protected
|
|
101
|
+
|
|
102
|
+
GET_PARAMS_BLACKLIST = [:script_name, :original_script_name]
|
|
103
|
+
|
|
104
|
+
def default_url_params
|
|
105
|
+
{}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def url(page)
|
|
109
|
+
@base_url_params ||= begin
|
|
110
|
+
url_params = merge_get_params(default_url_params)
|
|
111
|
+
url_params[:only_path] = true
|
|
112
|
+
merge_optional_params(url_params)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
url_params = @base_url_params.dup
|
|
116
|
+
add_current_page_param(url_params, page)
|
|
117
|
+
|
|
118
|
+
@template.url_for(url_params)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def merge_get_params(url_params)
|
|
122
|
+
if @template.respond_to?(:request) and @template.request
|
|
123
|
+
if @template.request.get?
|
|
124
|
+
symbolized_update(url_params, @template.params, GET_PARAMS_BLACKLIST)
|
|
125
|
+
elsif @template.request.respond_to?(:query_parameters)
|
|
126
|
+
symbolized_update(url_params, @template.request.query_parameters, GET_PARAMS_BLACKLIST)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
url_params
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def merge_optional_params(url_params)
|
|
133
|
+
symbolized_update(url_params, @options[:params]) if @options[:params]
|
|
134
|
+
url_params
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def add_current_page_param(url_params, page)
|
|
138
|
+
unless param_name.index(/[^\w-]/)
|
|
139
|
+
url_params[param_name.to_sym] = page
|
|
140
|
+
else
|
|
141
|
+
page_param = parse_query_parameters("#{param_name}=#{page}")
|
|
142
|
+
symbolized_update(url_params, page_param)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def parse_query_parameters(params)
|
|
149
|
+
Rack::Utils.parse_nested_query(params)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
::ActionView::Base.send :include, self
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'hanami/view'
|
|
2
|
+
require 'will_paginate/view_helpers'
|
|
3
|
+
require 'will_paginate/view_helpers/link_renderer'
|
|
4
|
+
|
|
5
|
+
module WillPaginate
|
|
6
|
+
module Hanami
|
|
7
|
+
module Helpers
|
|
8
|
+
include ViewHelpers
|
|
9
|
+
|
|
10
|
+
def will_paginate(collection, options = {}) #:nodoc:
|
|
11
|
+
options = options.merge(:renderer => LinkRenderer) unless options[:renderer]
|
|
12
|
+
str = super(collection, options)
|
|
13
|
+
str && raw(str)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class LinkRenderer < ViewHelpers::LinkRenderer
|
|
18
|
+
protected
|
|
19
|
+
|
|
20
|
+
def url(page)
|
|
21
|
+
str = File.join(request_env['SCRIPT_NAME'].to_s, request_env['PATH_INFO'])
|
|
22
|
+
params = request_env['rack.request.query_hash'].merge(param_name.to_s => page.to_s)
|
|
23
|
+
params.update @options[:params] if @options[:params]
|
|
24
|
+
str << '?' << build_query(params)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def request_env
|
|
28
|
+
@template.params.env
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def build_query(params)
|
|
32
|
+
Rack::Utils.build_nested_query params
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.included(base)
|
|
37
|
+
base.include Helpers
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
require 'will_paginate/core_ext'
|
|
3
|
+
require 'will_paginate/view_helpers'
|
|
4
|
+
require 'will_paginate/view_helpers/link_renderer_base'
|
|
5
|
+
|
|
6
|
+
module WillPaginate
|
|
7
|
+
module ViewHelpers
|
|
8
|
+
# This class does the heavy lifting of actually building the pagination
|
|
9
|
+
# links. It is used by +will_paginate+ helper internally.
|
|
10
|
+
class LinkRenderer < LinkRendererBase
|
|
11
|
+
|
|
12
|
+
# * +collection+ is a WillPaginate::Collection instance or any other object
|
|
13
|
+
# that conforms to that API
|
|
14
|
+
# * +options+ are forwarded from +will_paginate+ view helper
|
|
15
|
+
# * +template+ is the reference to the template being rendered
|
|
16
|
+
def prepare(collection, options, template)
|
|
17
|
+
super(collection, options)
|
|
18
|
+
@template = template
|
|
19
|
+
@container_attributes = @base_url_params = nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Process it! This method returns the complete HTML string which contains
|
|
23
|
+
# pagination links. Feel free to subclass LinkRenderer and change this
|
|
24
|
+
# method as you see fit.
|
|
25
|
+
def to_html
|
|
26
|
+
html = pagination.map do |item|
|
|
27
|
+
item.is_a?(Integer) ?
|
|
28
|
+
page_number(item) :
|
|
29
|
+
send(item)
|
|
30
|
+
end.join(@options[:link_separator])
|
|
31
|
+
|
|
32
|
+
@options[:container] ? html_container(html) : html
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns the subset of +options+ this instance was initialized with that
|
|
36
|
+
# represent HTML attributes for the container element of pagination links.
|
|
37
|
+
def container_attributes
|
|
38
|
+
@container_attributes ||= {
|
|
39
|
+
:role => 'navigation',
|
|
40
|
+
:"aria-label" => @template.will_paginate_translate(:container_aria_label) { 'Pagination' }
|
|
41
|
+
}.update @options.except(*(ViewHelpers.pagination_options.keys + [:renderer] - [:class]))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
protected
|
|
45
|
+
|
|
46
|
+
def page_number(page)
|
|
47
|
+
aria_label = @template.will_paginate_translate(:page_aria_label, :page => page.to_i) { "Page #{page}" }
|
|
48
|
+
if page == current_page
|
|
49
|
+
tag(:em, page, :class => 'current', :"aria-label" => aria_label, :"aria-current" => 'page')
|
|
50
|
+
else
|
|
51
|
+
link(page, page, :rel => rel_value(page), :"aria-label" => aria_label)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def gap
|
|
56
|
+
text = @template.will_paginate_translate(:page_gap) { '…' }
|
|
57
|
+
%(<span class="gap">#{text}</span>)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def previous_page
|
|
61
|
+
num = @collection.current_page > 1 && @collection.current_page - 1
|
|
62
|
+
aria_label = @template.will_paginate_translate(:previous_aria_label) { "Previous page" }
|
|
63
|
+
previous_or_next_page(num, @options[:previous_label], 'previous_page', aria_label)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def next_page
|
|
67
|
+
num = @collection.current_page < total_pages && @collection.current_page + 1
|
|
68
|
+
aria_label = @template.will_paginate_translate(:next_aria_label) { "Next page" }
|
|
69
|
+
previous_or_next_page(num, @options[:next_label], 'next_page', aria_label)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def previous_or_next_page(page, text, classname, aria_label = nil)
|
|
73
|
+
if page
|
|
74
|
+
link(text, page, :class => classname, :'aria-label' => aria_label)
|
|
75
|
+
else
|
|
76
|
+
tag(:span, text, :class => classname + ' disabled', :'aria-label' => aria_label)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def html_container(html)
|
|
81
|
+
tag(:div, html, container_attributes)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Returns URL params for +page_link_or_span+, taking the current GET params
|
|
85
|
+
# and <tt>:params</tt> option into account.
|
|
86
|
+
def url(page)
|
|
87
|
+
raise NotImplementedError
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def param_name
|
|
93
|
+
@options[:param_name].to_s
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def link(text, target, attributes = {})
|
|
97
|
+
if target.is_a?(Integer)
|
|
98
|
+
attributes[:rel] = rel_value(target)
|
|
99
|
+
target = url(target)
|
|
100
|
+
end
|
|
101
|
+
attributes[:href] = target
|
|
102
|
+
tag(:a, text, attributes)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def tag(name, value, attributes = {})
|
|
106
|
+
string_attributes = attributes.map do |pair|
|
|
107
|
+
unless pair.last.nil?
|
|
108
|
+
%( #{pair.first}="#{CGI::escapeHTML(pair.last.to_s)}")
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
"<#{name}#{string_attributes.compact.join("")}>#{value}</#{name}>"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def rel_value(page)
|
|
115
|
+
case page
|
|
116
|
+
when @collection.current_page - 1; 'prev'
|
|
117
|
+
when @collection.current_page + 1; 'next'
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def symbolized_update(target, other, blacklist = nil)
|
|
122
|
+
other.each_pair do |key, value|
|
|
123
|
+
key = key.to_sym
|
|
124
|
+
existing = target[key]
|
|
125
|
+
next if blacklist && blacklist.include?(key)
|
|
126
|
+
|
|
127
|
+
if value.respond_to?(:each_pair) and (existing.is_a?(Hash) or existing.nil?)
|
|
128
|
+
symbolized_update(existing || (target[key] = {}), value)
|
|
129
|
+
else
|
|
130
|
+
target[key] = value
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module WillPaginate
|
|
2
|
+
module ViewHelpers
|
|
3
|
+
# This class does the heavy lifting of actually building the pagination
|
|
4
|
+
# links. It is used by +will_paginate+ helper internally.
|
|
5
|
+
class LinkRendererBase
|
|
6
|
+
|
|
7
|
+
# * +collection+ is a WillPaginate::Collection instance or any other object
|
|
8
|
+
# that conforms to that API
|
|
9
|
+
# * +options+ are forwarded from +will_paginate+ view helper
|
|
10
|
+
def prepare(collection, options)
|
|
11
|
+
@collection = collection
|
|
12
|
+
@options = options
|
|
13
|
+
|
|
14
|
+
# reset values in case we're re-using this instance
|
|
15
|
+
@total_pages = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def pagination
|
|
19
|
+
items = @options[:page_links] ? windowed_page_numbers : []
|
|
20
|
+
items.unshift :previous_page
|
|
21
|
+
items.push :next_page
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
# Calculates visible page numbers using the <tt>:inner_window</tt> and
|
|
27
|
+
# <tt>:outer_window</tt> options.
|
|
28
|
+
def windowed_page_numbers
|
|
29
|
+
inner_window, outer_window = @options[:inner_window].to_i, @options[:outer_window].to_i
|
|
30
|
+
window_from = current_page - inner_window
|
|
31
|
+
window_to = current_page + inner_window
|
|
32
|
+
|
|
33
|
+
# adjust lower or upper limit if either is out of bounds
|
|
34
|
+
if window_to > total_pages
|
|
35
|
+
window_from -= window_to - total_pages
|
|
36
|
+
window_to = total_pages
|
|
37
|
+
end
|
|
38
|
+
if window_from < 1
|
|
39
|
+
window_to += 1 - window_from
|
|
40
|
+
window_from = 1
|
|
41
|
+
window_to = total_pages if window_to > total_pages
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# these are always visible
|
|
45
|
+
middle = window_from..window_to
|
|
46
|
+
|
|
47
|
+
# left window
|
|
48
|
+
if outer_window + 3 < middle.first # there's a gap
|
|
49
|
+
left = (1..(outer_window + 1)).to_a
|
|
50
|
+
left << :gap
|
|
51
|
+
else # runs into visible pages
|
|
52
|
+
left = 1...middle.first
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# right window
|
|
56
|
+
if total_pages - outer_window - 2 > middle.last # again, gap
|
|
57
|
+
right = ((total_pages - outer_window)..total_pages).to_a
|
|
58
|
+
right.unshift :gap
|
|
59
|
+
else # runs into visible pages
|
|
60
|
+
right = (middle.last + 1)..total_pages
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
left.to_a + middle.to_a + right.to_a
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def current_page
|
|
69
|
+
@collection.current_page
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def total_pages
|
|
73
|
+
@total_pages ||= @collection.total_pages
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|