paginate 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +14 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +83 -64
- data/README.md +146 -0
- data/Rakefile +9 -8
- data/gemfiles/rails3.gemfile +4 -0
- data/gemfiles/rails3.gemfile.lock +132 -0
- data/lib/paginate.rb +4 -0
- data/lib/paginate/active_record.rb +13 -1
- data/lib/paginate/base.rb +13 -4
- data/lib/paginate/config.rb +4 -2
- data/lib/paginate/extension.rb +14 -0
- data/lib/paginate/helper.rb +20 -46
- data/lib/paginate/renderer.rb +47 -63
- data/lib/paginate/renderer/list.rb +47 -0
- data/lib/paginate/renderer/more.rb +19 -0
- data/lib/paginate/version.rb +1 -1
- data/paginate.gemspec +2 -4
- data/spec/paginate/action_view_spec.rb +3 -128
- data/spec/paginate/activerecord_spec.rb +9 -9
- data/spec/paginate/base_spec.rb +17 -15
- data/spec/paginate/config_spec.rb +17 -1
- data/spec/paginate/{renderer_spec.rb → renderer/base_spec.rb} +5 -7
- data/spec/paginate/renderer/list_spec.rb +111 -0
- data/spec/paginate/renderer/more_spec.rb +38 -0
- data/spec/spec_helper.rb +10 -8
- data/spec/support/translations.yml +2 -0
- data/spec/support/views/application/_render.erb +1 -1
- metadata +34 -72
- data/README.rdoc +0 -96
data/lib/paginate.rb
CHANGED
@@ -4,6 +4,9 @@ require "paginate/base"
|
|
4
4
|
require "paginate/config"
|
5
5
|
require "paginate/helper"
|
6
6
|
require "paginate/renderer"
|
7
|
+
require "paginate/renderer/list"
|
8
|
+
require "paginate/renderer/more"
|
9
|
+
require "paginate/extension"
|
7
10
|
require "paginate/active_record"
|
8
11
|
require "paginate/action_controller"
|
9
12
|
|
@@ -16,4 +19,5 @@ end
|
|
16
19
|
Paginate.configure do |config|
|
17
20
|
config.param_name = :page
|
18
21
|
config.size = 10
|
22
|
+
config.renderer = Paginate::Renderer::List
|
19
23
|
end
|
@@ -1,5 +1,17 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
class Base
|
3
|
-
|
3
|
+
class << self
|
4
|
+
def inherited_with_paginate(subclass)
|
5
|
+
inherited_without_paginate subclass
|
6
|
+
subclass.send(:include, Paginate::Extension) if subclass.superclass == ActiveRecord::Base
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method_chain :inherited, :paginate
|
10
|
+
end
|
11
|
+
|
12
|
+
# Extend existing models
|
13
|
+
self.descendants.each do |model|
|
14
|
+
model.send(:include, Paginate::Extension) if model.superclass == ActiveRecord::Base
|
15
|
+
end
|
4
16
|
end
|
5
17
|
end
|
data/lib/paginate/base.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
module Paginate
|
2
2
|
class Base
|
3
3
|
attr_accessor :options
|
4
|
+
attr_accessor :scope
|
5
|
+
|
6
|
+
def initialize(scope, options = {})
|
7
|
+
@scope = scope
|
4
8
|
|
5
|
-
def initialize(options = {})
|
6
9
|
if options.kind_of?(Hash)
|
7
10
|
@options = options
|
8
11
|
else
|
9
|
-
@options = {:
|
12
|
+
@options = {page: options.to_i}
|
10
13
|
end
|
11
14
|
|
12
15
|
@options.reverse_merge!(Paginate::Config.to_hash)
|
@@ -21,7 +24,7 @@ module Paginate
|
|
21
24
|
end
|
22
25
|
|
23
26
|
def previous_page?
|
24
|
-
|
27
|
+
page > 1
|
25
28
|
end
|
26
29
|
|
27
30
|
def page
|
@@ -37,7 +40,13 @@ module Paginate
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def to_options
|
40
|
-
{
|
43
|
+
{limit: limit, offset: offset}
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_scope
|
47
|
+
scope
|
48
|
+
.limit(limit)
|
49
|
+
.offset(offset)
|
41
50
|
end
|
42
51
|
end
|
43
52
|
end
|
data/lib/paginate/config.rb
CHANGED
@@ -3,12 +3,14 @@ module Paginate
|
|
3
3
|
class << self
|
4
4
|
attr_accessor :size
|
5
5
|
attr_accessor :param_name
|
6
|
+
attr_accessor :renderer
|
6
7
|
end
|
7
8
|
|
8
9
|
def self.to_hash
|
9
10
|
{
|
10
|
-
:
|
11
|
-
:
|
11
|
+
size: size,
|
12
|
+
param_name: param_name,
|
13
|
+
renderer: renderer
|
12
14
|
}
|
13
15
|
end
|
14
16
|
end
|
data/lib/paginate/helper.rb
CHANGED
@@ -12,6 +12,7 @@ module Paginate
|
|
12
12
|
# * <tt>:id</tt>: the HTML id that will identify the pagination block.
|
13
13
|
# * <tt>:size</tt>: the page size. When not specified will default to <tt>Paginate::Config.size</tt>.
|
14
14
|
# * <tt>:param_name</tt>: the page param name. When not specified will default to <tt>Paginate::Config.param_name</tt>.
|
15
|
+
# * <tt>:renderer</tt>: A class that will be used to render the pagination. When not specified will default to <tt>Paginate::Renderer::List</tt>.
|
15
16
|
#
|
16
17
|
# <%= paginate @posts, proc {|page| posts_path(page) }
|
17
18
|
# <%= paginate @posts, :url => proc {|page| posts_path(page) }
|
@@ -20,16 +21,28 @@ module Paginate
|
|
20
21
|
#
|
21
22
|
def paginate(collection, *args)
|
22
23
|
options = args.extract_options!
|
23
|
-
|
24
|
+
|
25
|
+
param_name = [
|
26
|
+
options[:param_name],
|
27
|
+
Paginate::Config.param_name,
|
28
|
+
:page
|
29
|
+
].compact.first
|
30
|
+
|
31
|
+
renderer = [
|
32
|
+
options[:renderer],
|
33
|
+
Paginate::Config.renderer,
|
34
|
+
Paginate::Renderer::List
|
35
|
+
].compact.first
|
36
|
+
|
24
37
|
options.merge!({
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
|
38
|
+
collection: collection,
|
39
|
+
page: params[param_name],
|
40
|
+
param_name: param_name,
|
41
|
+
fullpath: request.fullpath
|
29
42
|
})
|
30
|
-
options.merge!(:url => args.first) if args.any?
|
31
43
|
|
32
|
-
|
44
|
+
options.merge!(url: args.first) if args.any?
|
45
|
+
renderer.new(self, options).render
|
33
46
|
end
|
34
47
|
|
35
48
|
# Override the original render method, so we can strip the additional
|
@@ -49,49 +62,10 @@ module Paginate
|
|
49
62
|
size = options.delete(:size) { Paginate::Config.size }
|
50
63
|
|
51
64
|
return super(*[*args, options], &block) unless paginated
|
52
|
-
|
53
65
|
collection = options.delete(:collection) { args.shift }
|
54
66
|
collection = collection[0, size]
|
55
67
|
|
56
68
|
super(collection, *[*args, options], &block)
|
57
69
|
end
|
58
|
-
|
59
|
-
# In order to iterate the correct items you have to skip the last collection's item.
|
60
|
-
# We added this helper to automatically skip the last item only if there's a next page.
|
61
|
-
#
|
62
|
-
# <% iterate @items do |item| %>
|
63
|
-
# <% end %>
|
64
|
-
#
|
65
|
-
# If you want to grab the iteration index as well just expect it as a block parameter.
|
66
|
-
#
|
67
|
-
# <% iterate @items do |item, i|
|
68
|
-
# <% end %>
|
69
|
-
#
|
70
|
-
# If you set a custom size while fetching items from database, you need to inform it while iterating.
|
71
|
-
#
|
72
|
-
# @items = Item.paginate(:page => 1, :size => 5)
|
73
|
-
#
|
74
|
-
# Then in your view:
|
75
|
-
#
|
76
|
-
# <% iterate @items, :size => 5 do |item| %>
|
77
|
-
# <% end %>
|
78
|
-
#
|
79
|
-
# You can receive the iteration counter by expecting two arguments.
|
80
|
-
#
|
81
|
-
# <% iterate @items do |item, i| do %>
|
82
|
-
# <% end %>
|
83
|
-
#
|
84
|
-
def iterate(collection, options = {}, &block)
|
85
|
-
options.reverse_merge!(:size => Paginate::Config.size)
|
86
|
-
yield_index = block.arity == 2
|
87
|
-
|
88
|
-
collection[0, options[:size]].each_with_index do |item, i|
|
89
|
-
if yield_index
|
90
|
-
yield item, i
|
91
|
-
else
|
92
|
-
yield item
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
70
|
end
|
97
71
|
end
|
data/lib/paginate/renderer.rb
CHANGED
@@ -1,73 +1,57 @@
|
|
1
1
|
module Paginate
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
if url.respond_to?(:call)
|
20
|
-
url = url.call(page).to_s.dup
|
21
|
-
else
|
22
|
-
url = url.dup
|
23
|
-
|
24
|
-
re = Regexp.new("([&?])#{Regexp.escape(options[:param_name].to_s)}=[^&]*")
|
25
|
-
url.gsub!(re, "\\1")
|
26
|
-
url.gsub!(/[\?&]$/, "")
|
27
|
-
url.gsub!(/&+/, "&")
|
28
|
-
url.gsub!(/\?&/, "?")
|
29
|
-
|
30
|
-
url << (url =~ /\?/ ? "&" : "?")
|
31
|
-
url << page.to_query(options[:param_name])
|
2
|
+
module Renderer
|
3
|
+
class Base
|
4
|
+
# Set the pagination options.
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
# Set the view context. You can use this object
|
8
|
+
# to call view and url helpers.
|
9
|
+
attr_reader :view_context
|
10
|
+
|
11
|
+
# Set the object with defines all pagination methods
|
12
|
+
# like `Paginate::Base#next_page?`.
|
13
|
+
attr_reader :processor
|
14
|
+
|
15
|
+
def initialize(view_context, options)
|
16
|
+
@view_context = view_context
|
17
|
+
@options = options.reverse_merge(Paginate::Config.to_hash)
|
18
|
+
@processor = Paginate::Base.new(nil, options)
|
32
19
|
end
|
33
20
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
def render
|
39
|
-
html = String.new
|
40
|
-
previous_label = I18n.t("paginate.previous")
|
41
|
-
previous_url = url_for(options[:page] - 1)
|
42
|
-
next_label = I18n.t("paginate.next")
|
43
|
-
next_url = url_for(options[:page] + 1)
|
44
|
-
page_label = I18n.t("paginate.page", options)
|
45
|
-
|
46
|
-
css = %w[ paginate ]
|
47
|
-
css << "disabled" unless processor.previous_page? || processor.next_page?
|
48
|
-
|
49
|
-
html << %[<ul class="#{css.join(" ")}">]
|
50
|
-
|
51
|
-
# Previous page
|
52
|
-
if processor.previous_page?
|
53
|
-
html << %[<li class="previous-page"><a href="#{previous_url}" title="#{previous_label}">#{previous_label}</a></li>]
|
54
|
-
else
|
55
|
-
html << %[<li class="previous-page disabled"><span title="#{previous_label}">#{previous_label}</span></li>]
|
21
|
+
# Return the URL for previous page.
|
22
|
+
def previous_url
|
23
|
+
url_for(processor.page - 1)
|
56
24
|
end
|
57
25
|
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
# Next page
|
62
|
-
if processor.next_page?
|
63
|
-
html << %[<li class="next-page"><a href="#{next_url}" title="#{next_label}">#{next_label}</a></li>]
|
64
|
-
else
|
65
|
-
html << %[<li class="next-page disabled"><span title="#{next_label}">#{next_label}</span></li>]
|
26
|
+
# Return the URL for next page.
|
27
|
+
def next_url
|
28
|
+
url_for(processor.page + 1)
|
66
29
|
end
|
67
30
|
|
68
|
-
|
69
|
-
|
70
|
-
|
31
|
+
# Compute the URL for a given page.
|
32
|
+
# It will keep track of all query string and replace the
|
33
|
+
# page parameter with the specified `page`.
|
34
|
+
def url_for(page)
|
35
|
+
url = options[:url] || options[:fullpath]
|
36
|
+
|
37
|
+
if url.respond_to?(:call)
|
38
|
+
url = url.call(page).to_s.dup
|
39
|
+
else
|
40
|
+
url = url.dup
|
41
|
+
|
42
|
+
re = Regexp.new("([&?])#{Regexp.escape(options[:param_name].to_s)}=[^&]*")
|
43
|
+
url.gsub!(re, "\\1")
|
44
|
+
url.gsub!(/[\?&]$/, "")
|
45
|
+
url.gsub!(/&+/, "&")
|
46
|
+
url.gsub!(/\?&/, "?")
|
47
|
+
|
48
|
+
url << (url =~ /\?/ ? "&" : "?")
|
49
|
+
url << page.to_query(options[:param_name])
|
50
|
+
end
|
51
|
+
|
52
|
+
url.gsub!(/&/, "&")
|
53
|
+
url
|
54
|
+
end
|
71
55
|
end
|
72
56
|
end
|
73
57
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Paginate
|
2
|
+
module Renderer
|
3
|
+
class List < Base
|
4
|
+
def previous_label
|
5
|
+
I18n.t("paginate.previous")
|
6
|
+
end
|
7
|
+
|
8
|
+
def next_label
|
9
|
+
I18n.t("paginate.next")
|
10
|
+
end
|
11
|
+
|
12
|
+
def page_label
|
13
|
+
I18n.t("paginate.page", page: processor.page)
|
14
|
+
end
|
15
|
+
|
16
|
+
def render
|
17
|
+
html = String.new
|
18
|
+
|
19
|
+
css = %w[ paginate ]
|
20
|
+
css << "disabled" unless processor.previous_page? || processor.next_page?
|
21
|
+
|
22
|
+
html << %[<ul class="#{css.join(" ")}">]
|
23
|
+
|
24
|
+
# Previous page
|
25
|
+
if processor.previous_page?
|
26
|
+
html << %[<li class="previous-page"><a href="#{previous_url}" title="#{previous_label}">#{previous_label}</a></li>]
|
27
|
+
else
|
28
|
+
html << %[<li class="previous-page disabled"><span title="#{previous_label}">#{previous_label}</span></li>]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Current page
|
32
|
+
html << %[<li class="page"><span>#{page_label}</span></li>]
|
33
|
+
|
34
|
+
# Next page
|
35
|
+
if processor.next_page?
|
36
|
+
html << %[<li class="next-page"><a href="#{next_url}" title="#{next_label}">#{next_label}</a></li>]
|
37
|
+
else
|
38
|
+
html << %[<li class="next-page disabled"><span title="#{next_label}">#{next_label}</span></li>]
|
39
|
+
end
|
40
|
+
|
41
|
+
html << %[</ul>]
|
42
|
+
|
43
|
+
html.html_safe
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Paginate
|
2
|
+
module Renderer
|
3
|
+
class More < Base
|
4
|
+
def more_label
|
5
|
+
I18n.t("paginate.more")
|
6
|
+
end
|
7
|
+
|
8
|
+
def render
|
9
|
+
return unless processor.next_page?
|
10
|
+
|
11
|
+
<<-HTML.html_safe
|
12
|
+
<p class="paginate">
|
13
|
+
<a class="more" href="#{next_url}" title="#{more_label}">#{more_label}</a>
|
14
|
+
</p>
|
15
|
+
HTML
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/paginate/version.rb
CHANGED
data/paginate.gemspec
CHANGED
@@ -20,9 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_development_dependency "nokogiri"
|
21
21
|
s.add_development_dependency "test_notifier"
|
22
22
|
s.add_development_dependency "sqlite3-ruby"
|
23
|
-
s.add_development_dependency "
|
24
|
-
s.add_development_dependency "
|
25
|
-
s.add_development_dependency "actionpack"
|
26
|
-
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "rails", "~> 4.0.0"
|
24
|
+
s.add_development_dependency "rspec", "~> 2.14.0.rc1"
|
27
25
|
s.add_development_dependency "pry-meta"
|
28
26
|
end
|
@@ -15,7 +15,7 @@ describe "ActionView support" do
|
|
15
15
|
@view.lookup_context.prefixes << "application"
|
16
16
|
@view.controller = @controller
|
17
17
|
@view.extend(Paginate::Helper)
|
18
|
-
@view.stub :
|
18
|
+
@view.stub request: @request
|
19
19
|
|
20
20
|
@helper = Object.new
|
21
21
|
@helper.extend(Paginate::Helper)
|
@@ -28,84 +28,6 @@ describe "ActionView support" do
|
|
28
28
|
I18n.locale = :en
|
29
29
|
end
|
30
30
|
|
31
|
-
it "displays pagination list" do
|
32
|
-
@request.fullpath = "/some/path?page=1"
|
33
|
-
html = render(:default, [])
|
34
|
-
|
35
|
-
expect(html.css("ul.paginate").count).to eql(1)
|
36
|
-
expect(html.css("ul.paginate > li").count).to eql(3)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "adds .disabled class when have no items" do
|
40
|
-
@request.fullpath = "/some/path"
|
41
|
-
html = render(:default, [])
|
42
|
-
|
43
|
-
expect(html.css("ul.paginate.disabled").first).to be
|
44
|
-
end
|
45
|
-
|
46
|
-
it "displays next page link" do
|
47
|
-
@request.fullpath = "/some/path?page=1"
|
48
|
-
html = render(:default, Array.new(11))
|
49
|
-
link = html.css("li.next-page > a").first
|
50
|
-
|
51
|
-
expect(link).to be
|
52
|
-
expect(link["href"]).to eql("/some/path?page=2")
|
53
|
-
expect(link.text).to eql("Next page")
|
54
|
-
end
|
55
|
-
|
56
|
-
it "displays next page link using proc as url" do
|
57
|
-
@request.fullpath = "/some/path?page=1"
|
58
|
-
html = render(:block_as_url, Array.new(11))
|
59
|
-
link = html.css("li.next-page > a").first
|
60
|
-
|
61
|
-
expect(link).to be
|
62
|
-
expect(link["href"]).to eql("/some/path/2")
|
63
|
-
expect(link.text).to eql("Next page")
|
64
|
-
end
|
65
|
-
|
66
|
-
it "displays previous page link" do
|
67
|
-
@params[:page] = 2
|
68
|
-
@request.fullpath = "/some/path?page=2"
|
69
|
-
html = render(:default, Array.new(11))
|
70
|
-
link = html.css("li.previous-page > a").first
|
71
|
-
|
72
|
-
expect(link).to be
|
73
|
-
expect(link["href"]).to eql("/some/path?page=1")
|
74
|
-
expect(link.text).to eql("Previous page")
|
75
|
-
end
|
76
|
-
|
77
|
-
it "disables element when have no next page" do
|
78
|
-
@request.fullpath = "/some/path?page=1"
|
79
|
-
html = render(:default, Array.new(10))
|
80
|
-
link = html.css("li.next-page > a").first
|
81
|
-
span = html.css("li.next-page.disabled > span").first
|
82
|
-
|
83
|
-
expect(link).not_to be
|
84
|
-
expect(span).to be
|
85
|
-
expect(span.text).to eql("Next page")
|
86
|
-
end
|
87
|
-
|
88
|
-
it "disables element when have no previous page" do
|
89
|
-
@request.fullpath = "/some/path?page=1"
|
90
|
-
html = render(:default, Array.new(10))
|
91
|
-
link = html.css("li.previous-page > a").first
|
92
|
-
span = html.css("li.previous-page.disabled > span").first
|
93
|
-
|
94
|
-
expect(link).not_to be
|
95
|
-
expect(span).to be
|
96
|
-
expect(span.text).to eql("Previous page")
|
97
|
-
end
|
98
|
-
|
99
|
-
it "displays current page" do
|
100
|
-
@params[:page] = 10
|
101
|
-
@request.fullpath = "/some/path?page=10"
|
102
|
-
html = render(:default, [])
|
103
|
-
span = html.css("li.page > span").first
|
104
|
-
|
105
|
-
expect(span).to be
|
106
|
-
expect(span.text).to eql("Page 10")
|
107
|
-
end
|
108
|
-
|
109
31
|
it "overrides render method" do
|
110
32
|
items = [*1..11].map do |i|
|
111
33
|
OpenStruct.new(:to_partial_path => "number", :value => i)
|
@@ -114,58 +36,11 @@ describe "ActionView support" do
|
|
114
36
|
html = render(:render, items)
|
115
37
|
end
|
116
38
|
|
117
|
-
it "translates strings" do
|
118
|
-
I18n.locale = :"pt-BR"
|
119
|
-
|
120
|
-
@params[:page] = 10
|
121
|
-
@request.fullpath = "/some/path?page=10"
|
122
|
-
html = render(:default, Array.new(11))
|
123
|
-
|
124
|
-
expect(html.css("li.page > span").text).to eql("Página 10")
|
125
|
-
expect(html.css("li.next-page > a").text).to eql("Próxima página")
|
126
|
-
expect(html.css("li.previous-page > a").text).to eql("Página anterior")
|
127
|
-
end
|
128
|
-
|
129
|
-
it "skips the last item while iterating" do
|
130
|
-
values = []
|
131
|
-
items = Array.new(11) {|i| "User#{i}" }
|
132
|
-
|
133
|
-
@helper.iterate items do |item|
|
134
|
-
values << item
|
135
|
-
end
|
136
|
-
|
137
|
-
expect(values).to eql(items[0, 10])
|
138
|
-
end
|
139
|
-
|
140
|
-
it "iterates all items when have less records than size" do
|
141
|
-
values = []
|
142
|
-
items = Array.new(8) {|i| "User#{i}" }
|
143
|
-
|
144
|
-
@helper.iterate items do |item|
|
145
|
-
values << item
|
146
|
-
end
|
147
|
-
|
148
|
-
expect(values).to eql(items[0, 8])
|
149
|
-
end
|
150
|
-
|
151
|
-
it "yields iteration counter" do
|
152
|
-
values = []
|
153
|
-
indices = []
|
154
|
-
items = Array.new(11) {|i| "User#{i}" }
|
155
|
-
|
156
|
-
@helper.iterate items do |item, i|
|
157
|
-
values << item
|
158
|
-
indices << i
|
159
|
-
end
|
160
|
-
|
161
|
-
expect(values).to eql(items[0, 10])
|
162
|
-
expect(indices).to eql([*0...10])
|
163
|
-
end
|
164
|
-
|
165
39
|
private
|
166
40
|
def render(view_name, items)
|
41
|
+
@controller.params = @params
|
167
42
|
view_info = Struct.new(:to_partial_path).new("#{view_name}")
|
168
|
-
Nokogiri @view.render(view_info, :
|
43
|
+
Nokogiri @view.render(view_info, items: items)
|
169
44
|
end
|
170
45
|
|
171
46
|
def load_view(name)
|