cells 3.10.1 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|