forked from kaminari/kaminari
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helpers.rb
126 lines (107 loc) · 3.48 KB
/
helpers.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
module Kaminari
module Helpers
class Tag
def initialize(renderer, options = {})
@renderer, @options = renderer, renderer.options.merge(options)
end
def to_s(locals = {})
@renderer.render :partial => "kaminari/#{self.class.name.demodulize.underscore}", :locals => @options.merge(locals)
end
private
def page_url_for(page)
@renderer.url_for @renderer.params.merge(:page => (page <= 1 ? nil : page))
end
end
class PrevSpan < Tag
end
class PrevLink < Tag
def to_s
super :prev_url => page_url_for(@options[:current_page] - 1)
end
end
class NextSpan < Tag
end
class NextLink < Tag
def to_s
super :next_url => page_url_for(@options[:current_page] + 1)
end
end
class PageLink < Tag
def to_s
super :page_url => page_url_for(@options[:page])
end
end
class CurrentPage < Tag
def to_s
super :page_url => page_url_for(@options[:page])
end
end
class FirstPageLink < PageLink
end
class LastPageLink < PageLink
end
class TruncatedSpan < Tag
end
class PaginationRenderer
attr_reader :options
def initialize(template, options)
@template, @options = template, options
@left, @window, @right = (options[:left] || options[:outer_window] || 1), (options[:window] || options[:inner_window] || 4), (options[:right] || options[:outer_window] || 1)
end
def to_s
suppress_logging_render_partial do
@template.content_tag :div, :class => 'pagination' do
tagify.join("\n").html_safe
end
end
end
def tagify
num_pages, current_page, left, window, right = @options[:num_pages], @options[:current_page], @left, @window, @right
tags = []
tags << (current_page > 1 ? PrevLink.new(self) : PrevSpan.new(self))
1.upto(num_pages) do |i|
if i == current_page
tags << CurrentPage.new(self, :page => i)
elsif (i <= left + 1) || ((num_pages - i) <= right) || ((i - current_page).abs <= window)
case i
when 1
tags << FirstPageLink.new(self, :page => i)
when num_pages
tags << LastPageLink.new(self, :page => i)
else
tags << PageLink.new(self, :page => i)
end
else
tags << TruncatedSpan.new(self) unless tags.last.is_a? TruncatedSpan
end
end
tags << (num_pages > current_page ? NextLink.new(self) : NextSpan.new(self))
end
private
def method_missing(meth, *args, &blk)
@template.send meth, *args, &blk
end
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
end
def paginate(scope, options = {}, &block)
PaginationRenderer.new self, options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages)
end
end
end