cells 3.10.1 → 3.11.0
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.
- data/.travis.yml +7 -0
- data/CHANGES.md +18 -0
- data/Gemfile +1 -1
- data/README.md +182 -57
- data/TODO.md +9 -0
- data/cells.gemspec +3 -1
- data/gemfiles/Gemfile.rails4-0 +2 -1
- data/gemfiles/Gemfile.rails4-1 +5 -3
- data/lib/cell/base.rb +33 -64
- data/lib/cell/base/prefixes.rb +27 -0
- data/lib/cell/base/self_contained.rb +13 -0
- data/lib/cell/base/view.rb +15 -0
- data/lib/cell/builder.rb +52 -53
- data/lib/cell/caching.rb +21 -4
- data/lib/cell/concept.rb +85 -0
- data/lib/cell/rails.rb +13 -6
- data/lib/cell/rails/view_model.rb +47 -6
- data/lib/cell/rendering.rb +13 -13
- data/lib/cell/test_case.rb +3 -3
- data/lib/cell/view_model.rb +151 -0
- data/lib/cells.rb +0 -60
- data/lib/cells/rails.rb +10 -5
- data/lib/cells/railtie.rb +2 -5
- data/lib/cells/version.rb +1 -1
- data/lib/generators/erb/concept_generator.rb +17 -0
- data/lib/generators/haml/concept_generator.rb +17 -0
- data/lib/generators/rails/concept_generator.rb +16 -0
- data/lib/generators/templates/concept/cell.rb +9 -0
- data/lib/generators/templates/concept/view.erb +7 -0
- data/lib/generators/templates/concept/view.haml +4 -0
- data/lib/generators/trailblazer/base.rb +21 -0
- data/lib/generators/trailblazer/view_generator.rb +18 -0
- data/test/app/cells/bassist_cell.rb +1 -1
- data/test/app/cells/record/views/layout.haml +2 -0
- data/test/app/cells/record/views/show.erb +1 -0
- data/test/app/cells/record/views/song.erb +1 -0
- data/test/app/cells/song/scale.haml +1 -0
- data/test/cell_module_test.rb +18 -37
- data/test/cells_module_test.rb +1 -1
- data/test/concept_generator_test.rb +26 -0
- data/test/concept_test.rb +78 -0
- data/test/dummy/Rakefile +1 -1
- data/test/dummy/app/assets/javascripts/application.js +2 -0
- data/test/dummy/app/cells/album/assets/album.js +1 -0
- data/test/dummy/app/concepts/song/assets/songs.js +1 -0
- data/test/dummy/config/application.rb +11 -6
- data/test/dummy/label/label.gemspec +2 -2
- data/test/helper_test.rb +2 -2
- data/test/prefixes_test.rb +75 -0
- data/test/rails/asset_pipeline_test.rb +20 -0
- data/test/rails/caching_test.rb +1 -9
- data/test/rails/cells_test.rb +2 -17
- data/test/rails/forms_test.rb +2 -1
- data/test/rails/integration_test.rb +199 -8
- data/test/rails/render_test.rb +2 -10
- data/test/rails/view_model_test.rb +135 -60
- data/test/rails_helper_api_test.rb +2 -1
- data/test/self_contained_test.rb +9 -2
- data/test/test_case_test.rb +2 -2
- data/test/test_helper.rb +2 -3
- metadata +117 -33
- checksums.yaml +0 -7
- data/test/dummy/app/controllers/musician_controller.rb +0 -36
- data/test/rails/router_test.rb +0 -45
@@ -0,0 +1,27 @@
|
|
1
|
+
# TODO: merge into Rails core.
|
2
|
+
# TODO: cache _prefixes on class layer.
|
3
|
+
module Cell::Base::Prefixes
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def _prefixes
|
7
|
+
self.class._prefixes
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def _prefixes
|
12
|
+
return [] if abstract?
|
13
|
+
_local_prefixes + superclass._prefixes
|
14
|
+
end
|
15
|
+
|
16
|
+
def _local_prefixes
|
17
|
+
[controller_path]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Instructs Cells to inherit views from a parent cell without having to inherit class code.
|
21
|
+
def inherit_views(parent)
|
22
|
+
define_method :_prefixes do
|
23
|
+
super() + parent._prefixes
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Enforces the new trailblazer directory layout where cells (or concepts in general) are
|
2
|
+
# fully self-contained in its own directory.
|
3
|
+
module Cell::Base::SelfContained
|
4
|
+
def self_contained!
|
5
|
+
extend Prefixes
|
6
|
+
end
|
7
|
+
|
8
|
+
module Prefixes
|
9
|
+
def _local_prefixes
|
10
|
+
super.collect { |prefix| "#{prefix}/views" }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Cell::Base::View < ActionView::Base
|
2
|
+
def self.prepare(modules)
|
3
|
+
# TODO: remove for 4.0 if PR https://github.com/rails/rails/pull/6826 is merged.
|
4
|
+
Class.new(self) do # DISCUSS: why are we mixing that stuff into this _anonymous_ class at all? that makes things super complicated.
|
5
|
+
include *modules.reverse
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def render(*args, &block)
|
10
|
+
options = args.first.is_a?(::Hash) ? args.first : {} # this is copied from #render by intention.
|
11
|
+
|
12
|
+
return controller.render(*args, &block) if options[:state] or options[:view]
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
data/lib/cell/builder.rb
CHANGED
@@ -1,72 +1,71 @@
|
|
1
1
|
module Cell
|
2
2
|
# Contains all methods for dynamically building a cell instance by using decider blocks.
|
3
|
-
|
3
|
+
#
|
4
|
+
# Design notes:
|
5
|
+
# * totally generic, doesn't know about parent_controller etc.
|
6
|
+
# * only dependency: constant.builders (I wanted to hide this from Cell::Base)
|
7
|
+
# * can easily be replaced or removed.
|
8
|
+
class Builder
|
9
|
+
def initialize(constant, exec_context) # TODO: evaluate usage of builders and implement using Uber::Options::Value.
|
10
|
+
@constant = constant
|
11
|
+
@exec_context = exec_context
|
12
|
+
@builders = @constant.builders # only dependency, must be a Cell::Base subclass.
|
13
|
+
end
|
14
|
+
|
4
15
|
# Creates a cell instance. Note that this method calls builders which were attached to the
|
5
16
|
# class with Cell::Base.build - this might lead to a different cell being returned.
|
6
|
-
def
|
7
|
-
class_from_cell_name(name).build_for(*args)
|
8
|
-
end # TODO: rename to #cell_for.
|
9
|
-
alias_method :cell_for, :create_cell_for
|
10
|
-
|
11
|
-
def build_for(*args) # DISCUSS: remove?
|
17
|
+
def call(*args)
|
12
18
|
build_class_for(*args).
|
13
|
-
create_cell(*args)
|
14
|
-
end
|
15
|
-
|
16
|
-
# Adds a builder to the cell class. Builders are used in #render_cell to find out the concrete
|
17
|
-
# class for rendering. This is helpful if you frequently want to render subclasses according
|
18
|
-
# to different circumstances (e.g. login situations) and you don't want to place these deciders in
|
19
|
-
# your view code.
|
20
|
-
#
|
21
|
-
# Passes the opts hash from #render_cell into the block. The block is executed in controller context.
|
22
|
-
# Multiple build blocks are ORed, if no builder matches the building cell is used.
|
23
|
-
#
|
24
|
-
# Example:
|
25
|
-
#
|
26
|
-
# Consider two different user box cells in your app.
|
27
|
-
#
|
28
|
-
# class AuthorizedUserBox < UserInfoBox
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# class AdminUserBox < UserInfoBox
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# Now you don't want to have deciders all over your views - use a declarative builder.
|
35
|
-
#
|
36
|
-
# UserInfoBox.build do |opts|
|
37
|
-
# AuthorizedUserBox if user_signed_in?
|
38
|
-
# AdminUserBox if admin_signed_in?
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# In your view #render_cell will instantiate the right cell for you now.
|
42
|
-
def build(&block)
|
43
|
-
builders << block
|
44
|
-
end
|
45
|
-
|
46
|
-
# The cell class constant for +cell_name+.
|
47
|
-
def class_from_cell_name(cell_name)
|
48
|
-
"#{cell_name}_cell".classify.constantize
|
49
|
-
end
|
50
|
-
|
51
|
-
# Override this if you want to receive arguments right in the cell constructor.
|
52
|
-
def create_cell(*args)
|
53
19
|
new(*args)
|
54
20
|
end
|
55
21
|
|
56
22
|
private
|
57
23
|
def build_class_for(*args)
|
58
|
-
builders.each do |blk|
|
24
|
+
@builders.each do |blk|
|
59
25
|
klass = run_builder_block(blk, *args) and return klass
|
60
26
|
end
|
61
|
-
|
27
|
+
@constant
|
62
28
|
end
|
63
29
|
|
64
30
|
def run_builder_block(block, *args)
|
65
|
-
|
31
|
+
@exec_context.instance_exec(*args, &block)
|
66
32
|
end
|
67
33
|
|
68
|
-
|
69
|
-
|
70
|
-
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
# Adds a builder to the cell class. Builders are used in #render_cell to find out the concrete
|
37
|
+
# class for rendering. This is helpful if you frequently want to render subclasses according
|
38
|
+
# to different circumstances (e.g. login situations) and you don't want to place these deciders in
|
39
|
+
# your view code.
|
40
|
+
#
|
41
|
+
# Passes the opts hash from #render_cell into the block. The block is executed in controller context.
|
42
|
+
# Multiple build blocks are ORed, if no builder matches the building cell is used.
|
43
|
+
#
|
44
|
+
# Example:
|
45
|
+
#
|
46
|
+
# Consider two different user box cells in your app.
|
47
|
+
#
|
48
|
+
# class AuthorizedUserBox < UserInfoBox
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# class AdminUserBox < UserInfoBox
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# Now you don't want to have deciders all over your views - use a declarative builder.
|
55
|
+
#
|
56
|
+
# UserInfoBox.build do |opts|
|
57
|
+
# AuthorizedUserBox if user_signed_in?
|
58
|
+
# AdminUserBox if admin_signed_in?
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# In your view #render_cell will instantiate the right cell for you now.
|
62
|
+
def build(&block)
|
63
|
+
builders << block
|
64
|
+
end
|
65
|
+
|
66
|
+
def builders
|
67
|
+
@builders ||= []
|
68
|
+
end
|
69
|
+
end # ClassMethods
|
71
70
|
end
|
72
71
|
end
|
data/lib/cell/caching.rb
CHANGED
@@ -50,9 +50,7 @@ module Cell
|
|
50
50
|
key = self.class.state_cache_key(state, self.class.version_procs[state].evaluate(self, *args))
|
51
51
|
options = self.class.cache_options.eval(state, self, *args)
|
52
52
|
|
53
|
-
|
54
|
-
super(state, *args)
|
55
|
-
end
|
53
|
+
fetch_from_cache_for(key, options) { super(state, *args) }
|
56
54
|
end
|
57
55
|
|
58
56
|
def cache_configured?
|
@@ -67,8 +65,27 @@ module Cell
|
|
67
65
|
end
|
68
66
|
|
69
67
|
private
|
68
|
+
def fetch_from_cache_for(key, options)
|
69
|
+
cache_store.fetch(key, options) do
|
70
|
+
yield
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
70
74
|
def state_cached?(state)
|
71
75
|
self.class.version_procs.has_key?(state)
|
72
76
|
end
|
73
|
-
|
77
|
+
|
78
|
+
|
79
|
+
module Notifications
|
80
|
+
def fetch_from_cache_for(key, options)
|
81
|
+
ActiveSupport::Notifications.instrument("read_fragment.action_controller", :key => key) do
|
82
|
+
cache_store.fetch(key, options) do
|
83
|
+
ActiveSupport::Notifications.instrument("write_fragment.action_controller", :key => key) do
|
84
|
+
yield
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end # Caching
|
74
91
|
end
|
data/lib/cell/concept.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# TODO: deprecate parent_controller, ViewModel
|
2
|
+
class Cell::Concept < Cell::ViewModel
|
3
|
+
abstract!
|
4
|
+
|
5
|
+
# TODO: this should be in Helper or something. this should be the only entry point from controller/view.
|
6
|
+
class << self
|
7
|
+
def cell_for(name, controller, *args)
|
8
|
+
Cell::Builder.new(name.classify.constantize, controller).call(controller, *args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def controller_path
|
12
|
+
# TODO: cache on class level
|
13
|
+
# DISCUSS: only works with trailblazer style directories. this is a bit risky but i like it.
|
14
|
+
# applies to Comment::Cell, Comment::Cell::Form, etc.
|
15
|
+
name.sub(/::Cell/, '').underscore unless anonymous?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def concept(name, *args, &block)
|
20
|
+
self.class.cell(name, parent_controller, *args, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
self_contained!
|
24
|
+
|
25
|
+
# DISCUSS: experimental, allows to render layouts from the partial view directory instead of a global one.
|
26
|
+
module Rendering
|
27
|
+
def view_renderer
|
28
|
+
@_view_renderer ||= Renderer.new(lookup_context)
|
29
|
+
end
|
30
|
+
|
31
|
+
if Cell.rails_version >= 3.2
|
32
|
+
def _normalize_layout(value) # 3.2+
|
33
|
+
value
|
34
|
+
end
|
35
|
+
else
|
36
|
+
def _normalize_options(options) # FIXME: for rails 3.1, only. in 3.2+ it's _normalize_layout.
|
37
|
+
super
|
38
|
+
|
39
|
+
if options[:layout]
|
40
|
+
options[:layout].sub!("layouts/", "")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Renderer < ActionView::Renderer
|
47
|
+
def render_template(context, options) # Rails 4.0 # FIXME: make that simpler to override in rails core.
|
48
|
+
TemplateRenderer.new(@lookup_context).render(context, options)
|
49
|
+
end
|
50
|
+
|
51
|
+
def _template_renderer # Rails 3.x
|
52
|
+
@_template_renderer ||= TemplateRenderer.new(@lookup_context)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
class TemplateRenderer < ActionView::TemplateRenderer
|
57
|
+
def render(context, options)
|
58
|
+
@options = options
|
59
|
+
super
|
60
|
+
end
|
61
|
+
|
62
|
+
def find_layout(layout, keys)
|
63
|
+
resolve_layout(layout, keys, [formats.first])
|
64
|
+
end
|
65
|
+
|
66
|
+
def resolve_layout(layout, keys, formats)
|
67
|
+
details = @details ? @details.dup : {} # FIXME: provide the entire Renderer layer here. this is to make it compatible with Rails 3.1.
|
68
|
+
details[:formats] = formats
|
69
|
+
|
70
|
+
case layout
|
71
|
+
when String
|
72
|
+
find_args = [layout, @options[:prefixes], false, keys, details]
|
73
|
+
find_args = [layout, @options[:prefixes], false, keys] if Cell.rails_version.~ 3.1
|
74
|
+
find_template(*find_args)
|
75
|
+
when Proc
|
76
|
+
resolve_layout(layout.call, keys, formats)
|
77
|
+
else
|
78
|
+
layout
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end # Rendering
|
83
|
+
|
84
|
+
include Rendering
|
85
|
+
end
|
data/lib/cell/rails.rb
CHANGED
@@ -8,6 +8,12 @@ module Cell
|
|
8
8
|
abstract!
|
9
9
|
delegate :session, :params, :request, :config, :env, :url_options, :to => :parent_controller
|
10
10
|
|
11
|
+
class Builder < Cell::Builder
|
12
|
+
def run_builder_block(block, controller, *args)
|
13
|
+
super(block, *args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
11
17
|
class << self
|
12
18
|
def cache_store
|
13
19
|
# FIXME: i'd love to have an initializer in the cells gem that _sets_ the cache_store attr instead of overriding here.
|
@@ -20,10 +26,11 @@ module Cell
|
|
20
26
|
expire_cache_key_for(key, cache_store ,*args)
|
21
27
|
end
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
def
|
26
|
-
|
29
|
+
# Main entry point for instantiating cells.
|
30
|
+
|
31
|
+
def cell_for(name, controller, *args)
|
32
|
+
# FIXME: too much redundancy from Base.
|
33
|
+
Builder.new(class_from_cell_name(name), controller).call(controller, *args) # use Cell::Rails::Builder.
|
27
34
|
end
|
28
35
|
end
|
29
36
|
|
@@ -51,7 +58,7 @@ module Cell
|
|
51
58
|
end
|
52
59
|
end
|
53
60
|
include DSL
|
54
|
-
|
55
|
-
autoload :ViewModel, "cell/rails/view_model"
|
56
61
|
end
|
57
62
|
end
|
63
|
+
|
64
|
+
require "cell/rails/view_model" # TODO: remove in 4.0.
|
@@ -14,14 +14,53 @@ class Cell::Rails
|
|
14
14
|
# properties :title, :body
|
15
15
|
attr_reader :model
|
16
16
|
|
17
|
+
|
18
|
+
def self.included(*)
|
19
|
+
ActiveSupport::Deprecation.warn("The Cell::Rails::ViewModel module is deprecated and will be removed in Cells 4.0. Please inherit: `class SongCell < Cell::ViewModel`. Thanks and don't forget to smile.")
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
module Helpers
|
26
|
+
# DISCUSS: highest level API method. add #cell here.
|
27
|
+
def collection(name, controller, array, method=:show, builder=Cell::Rails)
|
28
|
+
# FIXME: this is the problem in Concept cells, we don't wanna call Cell::Rails.cell_for here.
|
29
|
+
array.collect { |model| builder.cell_for(name, controller, model).call(method) }.join("\n").html_safe
|
30
|
+
end
|
31
|
+
|
32
|
+
# TODO: this should be in Helper or something. this should be the only entry point from controller/view.
|
33
|
+
def cell(name, controller, *args, &block) # classic Rails fuzzy API.
|
34
|
+
if args.first.is_a?(Hash) and array = args.first[:collection]
|
35
|
+
return collection(name, controller, array)
|
36
|
+
end
|
37
|
+
|
38
|
+
Cell::Rails.cell_for(name, controller, *args, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
extend Helpers # FIXME: do we really need ViewModel::cell/::collection ?
|
42
|
+
|
43
|
+
|
17
44
|
module ClassMethods
|
18
45
|
def property(*names)
|
19
46
|
delegate *names, :to => :model
|
20
47
|
end
|
48
|
+
|
49
|
+
include Helpers
|
21
50
|
end
|
22
51
|
extend ActiveSupport::Concern
|
23
52
|
|
24
53
|
|
54
|
+
def cell(name, *args)
|
55
|
+
self.class.cell(name, parent_controller, *args)
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def initialize(*args)
|
60
|
+
super
|
61
|
+
_prepare_context # happens in AV::Base at the bottom.
|
62
|
+
end
|
63
|
+
|
25
64
|
def render(options={})
|
26
65
|
if options.is_a?(Hash)
|
27
66
|
options.reverse_merge!(:view => state_for_implicit_render)
|
@@ -32,8 +71,10 @@ class Cell::Rails
|
|
32
71
|
super
|
33
72
|
end
|
34
73
|
|
35
|
-
def call
|
36
|
-
|
74
|
+
def call(state=:show)
|
75
|
+
# it is ok to call to_s.html_safe here as #call is a defined rendering method.
|
76
|
+
# DISCUSS: IN CONCEPT: render( view: implicit_state)
|
77
|
+
render_state(state).to_s.html_safe
|
37
78
|
end
|
38
79
|
|
39
80
|
private
|
@@ -45,9 +86,9 @@ class Cell::Rails
|
|
45
86
|
caller[1].match(/`(\w+)/)[1]
|
46
87
|
end
|
47
88
|
|
48
|
-
def implicit_state
|
49
|
-
|
50
|
-
end
|
89
|
+
# def implicit_state
|
90
|
+
# controller_path.split("/").last
|
91
|
+
# end
|
51
92
|
end
|
52
93
|
|
53
94
|
|
@@ -109,7 +150,7 @@ class Cell::Rails
|
|
109
150
|
end
|
110
151
|
|
111
152
|
# FIXME: fix that in rails core.
|
112
|
-
if Cell.
|
153
|
+
if Cell.rails_version.~("4.0", "4.1")
|
113
154
|
include LinkToHelper
|
114
155
|
else
|
115
156
|
include ActionView::Helpers::UrlHelper
|
data/lib/cell/rendering.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module Cell
|
2
2
|
module Rendering
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
|
4
|
+
|
5
5
|
# Invoke the state method for +state+ which usually renders something nice.
|
6
6
|
def render_state(state, *args)
|
7
7
|
process(state, *args)
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
# Renders the view for the current state and returns the markup.
|
11
11
|
# Don't forget to return the markup itself from the state method.
|
12
12
|
#
|
@@ -18,7 +18,7 @@ module Cell
|
|
18
18
|
# +:inline+:: Renders an inline template as state view. See ActionView::Base#render for details.
|
19
19
|
# +:file+:: Specifies the name of the file template to render.
|
20
20
|
# +:nothing+:: Doesn't invoke the rendering process.
|
21
|
-
# +:state+:: Instantly invokes another rendering cycle for the passed state and returns. You may pass arbitrary state-args to the called state.
|
21
|
+
# +:state+:: Instantly invokes another rendering cycle for the passed state and returns. You may pass arbitrary state-args to the called state.
|
22
22
|
# +:format+:: Sets a different template format, e.g. +:json+. Use this option with caution as it currently modifies the global format variable. This might lead to unexpected subsequent render behaviour due to a design flaw in Rails.
|
23
23
|
#
|
24
24
|
# Example:
|
@@ -56,7 +56,7 @@ module Cell
|
|
56
56
|
#
|
57
57
|
# === Using states instead of helpers
|
58
58
|
#
|
59
|
-
# Sometimes it's useful to not only render a view but also invoke the associated state. This is
|
59
|
+
# Sometimes it's useful to not only render a view but also invoke the associated state. This is
|
60
60
|
# especially helpful when replacing helpers. Do that with <tt>render :state</tt>.
|
61
61
|
#
|
62
62
|
# def show_cheap_item(item)
|
@@ -72,34 +72,34 @@ module Cell
|
|
72
72
|
def render(*args)
|
73
73
|
render_view_for(self.action_name, *args)
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
private
|
77
77
|
# Renders the view belonging to the given state. Will raise ActionView::MissingTemplate
|
78
78
|
# if it can't find a view.
|
79
79
|
def render_view_for(state, *args)
|
80
80
|
opts = args.first.is_a?(::Hash) ? args.shift : {}
|
81
|
-
|
81
|
+
|
82
82
|
return "" if opts[:nothing]
|
83
|
-
|
83
|
+
|
84
84
|
if opts[:state]
|
85
85
|
opts[:text] = render_state(opts.delete(:state), *args)
|
86
86
|
elsif (opts.keys & [:text, :inline, :file]).blank?
|
87
87
|
process_opts_for(opts, state)
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
render_to_string(opts).html_safe # ActionView::Template::Text doesn't do that for us.
|
91
91
|
end
|
92
|
-
|
93
|
-
|
92
|
+
|
93
|
+
|
94
94
|
module ClassMethods
|
95
95
|
# Main entry point for #render_cell.
|
96
96
|
def render_cell_for(name, state, *args)
|
97
|
-
cell =
|
97
|
+
cell = cell_for(name, *args)
|
98
98
|
yield cell if block_given?
|
99
|
-
|
99
|
+
|
100
100
|
render_cell_state(cell, state, *args)
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
private
|
104
104
|
def render_cell_state(cell, state, *args)
|
105
105
|
cell.render_state(state, *args)
|