cells 3.11.3 → 4.0.0.beta1

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.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +15 -13
  4. data/Appraisals +23 -0
  5. data/CHANGES.md +20 -3
  6. data/Gemfile +5 -7
  7. data/README.md +317 -236
  8. data/Rakefile +1 -1
  9. data/TODO.md +3 -0
  10. data/cells.gemspec +19 -28
  11. data/gemfiles/rails3.2.gemfile +14 -0
  12. data/gemfiles/rails4.0.gemfile +14 -0
  13. data/gemfiles/rails4.1.gemfile +15 -0
  14. data/gemfiles/rails4.2.gemfile +14 -0
  15. data/lib/cell.rb +28 -21
  16. data/lib/cell/caching.rb +10 -22
  17. data/lib/cell/caching/notification.rb +15 -0
  18. data/lib/cell/concept.rb +4 -69
  19. data/lib/cell/development.rb +11 -0
  20. data/lib/{cells → cell}/engines.rb +1 -1
  21. data/lib/cell/layout.rb +20 -0
  22. data/lib/cell/partial.rb +17 -0
  23. data/lib/cell/{base/prefixes.rb → prefixes.rb} +1 -1
  24. data/lib/cell/rails.rb +58 -50
  25. data/lib/cell/railtie.rb +60 -0
  26. data/lib/cell/{base/self_contained.rb → self_contained.rb} +1 -1
  27. data/lib/cell/templates.rb +60 -0
  28. data/lib/cell/test_case.rb +4 -162
  29. data/lib/cell/testing.rb +15 -0
  30. data/lib/cell/twin.rb +11 -29
  31. data/lib/cell/version.rb +10 -0
  32. data/lib/cell/view_model.rb +196 -88
  33. data/lib/cells.rb +1 -20
  34. data/lib/rails/generators/cell/cell_generator.rb +43 -0
  35. data/lib/rails/generators/cell/templates/cell.rb.erb +8 -0
  36. data/lib/{generators/templates/concept → rails/generators/cell/templates}/view.erb +0 -0
  37. data/lib/{generators/templates/concept → rails/generators/cell/templates}/view.haml +0 -0
  38. data/lib/rails/generators/cell/templates/view.slim +2 -0
  39. data/lib/rails/generators/concept/concept_generator.rb +38 -0
  40. data/lib/{generators/templates/concept/cell.rb → rails/generators/concept/templates/concept.rb.erb} +2 -2
  41. data/lib/{generators → rails/generators/concept}/templates/view.erb +0 -0
  42. data/lib/{generators → rails/generators/concept}/templates/view.haml +0 -0
  43. data/lib/rails/generators/concept/templates/view.slim +2 -0
  44. data/lib/rails/generators/test_unit/cell/cell_generator.rb +21 -0
  45. data/lib/{generators/templates/cell_test.rb → rails/generators/test_unit/cell/templates/unit_test.rb.erb} +3 -3
  46. data/lib/rails/generators/test_unit/concept/concept_generator.rb +21 -0
  47. data/lib/rails/generators/test_unit/concept/templates/unit_test.rb.erb +11 -0
  48. data/lib/{cells → tasks}/cells.rake +0 -0
  49. data/test/builder_test.rb +58 -0
  50. data/test/caching_test.rb +298 -0
  51. data/test/cell_benchmark.rb +32 -0
  52. data/test/cell_generator_test.rb +51 -82
  53. data/test/cell_test.rb +8 -23
  54. data/test/concept_generator_test.rb +22 -13
  55. data/test/concept_test.rb +41 -75
  56. data/test/dummy/app/views/musician/hamlet.html.erb +1 -0
  57. data/test/dummy/config/application.rb +21 -8
  58. data/test/{app/cells/bassist/play.html.erb → fixtures/bassist/play.erb} +0 -0
  59. data/test/fixtures/concepts/record/views/layout.erb +1 -0
  60. data/test/{app → fixtures}/concepts/record/views/show.erb +0 -0
  61. data/test/{app → fixtures}/concepts/record/views/song.erb +0 -0
  62. data/test/fixtures/inherit_views_test/popper/tap.erb +1 -0
  63. data/test/fixtures/inherit_views_test/tapper/play.erb +1 -0
  64. data/test/fixtures/inherit_views_test/tapper/tap.erb +1 -0
  65. data/test/fixtures/partial_test/with_partial/show.erb +1 -0
  66. data/test/fixtures/partials/_show.html.erb +1 -0
  67. data/test/fixtures/partials/_show.xml.erb +1 -0
  68. data/test/fixtures/song/ivar.erb +1 -0
  69. data/test/fixtures/song/show.erb +1 -0
  70. data/test/fixtures/song/with_erb.erb +4 -0
  71. data/test/fixtures/song/with_html.erb +1 -0
  72. data/test/fixtures/song/with_locals.erb +2 -0
  73. data/test/fixtures/song_with_layout/happy.erb +1 -0
  74. data/test/fixtures/song_with_layout/merry.erb +1 -0
  75. data/test/fixtures/song_with_layout/show.erb +1 -0
  76. data/test/fixtures/song_with_layout/show_with_layout.erb +1 -0
  77. data/test/fixtures/templates_caching_test/song/show.erb +1 -0
  78. data/test/fixtures/url_helper_test/song/edit.erb +8 -0
  79. data/test/fixtures/url_helper_test/song/with_block.erb +2 -0
  80. data/test/fixtures/url_helper_test/song/with_capture.erb +4 -0
  81. data/test/fixtures/url_helper_test/song/with_content_tag.erb +6 -0
  82. data/test/fixtures/url_helper_test/song/with_form_for_block.erb +3 -0
  83. data/test/fixtures/url_helper_test/song/with_link_to.erb +3 -0
  84. data/test/layout_test.rb +57 -0
  85. data/test/partial_test.rb +27 -0
  86. data/test/prefixes_test.rb +36 -10
  87. data/test/public_test.rb +42 -0
  88. data/test/rails_extensions_test.rb +51 -0
  89. data/test/render_test.rb +103 -0
  90. data/test/templates_test.rb +45 -0
  91. data/test/test_case_test.rb +21 -122
  92. data/test/test_helper.rb +37 -33
  93. data/test/twin_test.rb +3 -7
  94. data/test/url_helper_test.rb +89 -0
  95. metadata +92 -357
  96. data/gemfiles/Gemfile.rails3-0 +0 -7
  97. data/gemfiles/Gemfile.rails3-1 +0 -7
  98. data/gemfiles/Gemfile.rails3-2 +0 -7
  99. data/gemfiles/Gemfile.rails4-0 +0 -12
  100. data/gemfiles/Gemfile.rails4-1 +0 -12
  101. data/lib/cell/base.rb +0 -82
  102. data/lib/cell/base/view.rb +0 -15
  103. data/lib/cell/builder.rb +0 -71
  104. data/lib/cell/deprecations.rb +0 -41
  105. data/lib/cell/dsl.rb +0 -7
  106. data/lib/cell/rack.rb +0 -32
  107. data/lib/cell/rails/helper_api.rb +0 -37
  108. data/lib/cell/rails/view_model.rb +0 -159
  109. data/lib/cell/rails3_0_strategy.rb +0 -82
  110. data/lib/cell/rails3_1_strategy.rb +0 -40
  111. data/lib/cell/rails4_0_strategy.rb +0 -39
  112. data/lib/cell/rails4_1_strategy.rb +0 -40
  113. data/lib/cell/rendering.rb +0 -109
  114. data/lib/cells/rails.rb +0 -86
  115. data/lib/cells/railtie.rb +0 -38
  116. data/lib/cells/version.rb +0 -3
  117. data/lib/generators/USAGE +0 -30
  118. data/lib/generators/cells/base.rb +0 -22
  119. data/lib/generators/cells/cell_generator.rb +0 -15
  120. data/lib/generators/cells/view_generator.rb +0 -18
  121. data/lib/generators/erb/cell_generator.rb +0 -15
  122. data/lib/generators/erb/concept_generator.rb +0 -17
  123. data/lib/generators/haml/cell_generator.rb +0 -17
  124. data/lib/generators/haml/concept_generator.rb +0 -17
  125. data/lib/generators/rails/cell_generator.rb +0 -16
  126. data/lib/generators/rails/concept_generator.rb +0 -16
  127. data/lib/generators/slim/cell_generator.rb +0 -17
  128. data/lib/generators/templates/cell.rb +0 -9
  129. data/lib/generators/templates/view.slim +0 -4
  130. data/lib/generators/test_unit/cell_generator.rb +0 -14
  131. data/lib/generators/trailblazer/base.rb +0 -21
  132. data/lib/generators/trailblazer/view_generator.rb +0 -18
  133. data/test/app/cells/album/views/cover.haml +0 -1
  134. data/test/app/cells/bad_guitarist/_dii.html.erb +0 -1
  135. data/test/app/cells/bad_guitarist_cell.rb +0 -2
  136. data/test/app/cells/bassist/_dii.html.erb +0 -1
  137. data/test/app/cells/bassist/ahem.html.erb +0 -1
  138. data/test/app/cells/bassist/compose.html.erb +0 -1
  139. data/test/app/cells/bassist/contact_form.html.erb +0 -1
  140. data/test/app/cells/bassist/form_for.erb +0 -3
  141. data/test/app/cells/bassist/form_for_in_haml.haml +0 -2
  142. data/test/app/cells/bassist/jam.html.erb +0 -3
  143. data/test/app/cells/bassist/play.js.erb +0 -1
  144. data/test/app/cells/bassist/pose.html.erb +0 -1
  145. data/test/app/cells/bassist/promote.html.erb +0 -1
  146. data/test/app/cells/bassist/provoke.html.erb +0 -1
  147. data/test/app/cells/bassist/shout.html.erb +0 -1
  148. data/test/app/cells/bassist/sing.html.haml +0 -1
  149. data/test/app/cells/bassist/slap.html.erb +0 -1
  150. data/test/app/cells/bassist/yell.en.html.erb +0 -1
  151. data/test/app/cells/bassist_cell.rb +0 -25
  152. data/test/app/cells/club_security.rb +0 -2
  153. data/test/app/cells/club_security/guard/help.html.erb +0 -1
  154. data/test/app/cells/club_security/guard_cell.rb +0 -6
  155. data/test/app/cells/club_security/medic/help.html.erb +0 -1
  156. data/test/app/cells/club_security/medic_cell.rb +0 -8
  157. data/test/app/cells/layouts/b.erb +0 -1
  158. data/test/app/cells/layouts/metal.html.erb +0 -1
  159. data/test/app/cells/rails_helper_api_test/bassist/edit.html.erb +0 -5
  160. data/test/app/cells/shouter/sing.html.erb +0 -1
  161. data/test/app/cells/song/dashboard.haml +0 -7
  162. data/test/app/cells/song/details.html.haml +0 -1
  163. data/test/app/cells/song/info.html.haml +0 -1
  164. data/test/app/cells/song/lyrics.html.haml +0 -6
  165. data/test/app/cells/song/plays.haml +0 -1
  166. data/test/app/cells/song/scale.haml +0 -1
  167. data/test/app/cells/song/show.html.haml +0 -3
  168. data/test/app/cells/song/title.html.haml +0 -1
  169. data/test/app/cells/trumpeter/promote.html.erb +0 -1
  170. data/test/app/cells/trumpeter_cell.rb +0 -8
  171. data/test/app/cells/view_model_test/comments/show.haml +0 -7
  172. data/test/app/concepts/record/views/layout.haml +0 -2
  173. data/test/app/views/shared/_dong.html.erb +0 -1
  174. data/test/cell_module_test.rb +0 -170
  175. data/test/cells_module_test.rb +0 -27
  176. data/test/deprecations_test.rb +0 -101
  177. data/test/dummy/app/helpers/application_helper.rb +0 -2
  178. data/test/dummy/app/views/musician/hamlet.html.haml +0 -1
  179. data/test/dummy/config/environments/development.rb +0 -16
  180. data/test/dummy/config/environments/production.rb +0 -46
  181. data/test/dummy/config/environments/test.rb +0 -33
  182. data/test/dummy/db/test.sqlite3 +0 -0
  183. data/test/dummy/label/app/cells/label/show.erb +0 -1
  184. data/test/dummy/label/app/cells/label_cell.rb +0 -5
  185. data/test/dummy/label/label.gemspec +0 -20
  186. data/test/dummy/label/lib/label.rb +0 -4
  187. data/test/dummy/label/lib/label/version.rb +0 -3
  188. data/test/dummy/public/404.html +0 -26
  189. data/test/dummy/public/422.html +0 -26
  190. data/test/dummy/public/500.html +0 -26
  191. data/test/dummy/public/favicon.ico +0 -0
  192. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  193. data/test/helper_test.rb +0 -81
  194. data/test/rack_test.rb +0 -32
  195. data/test/rails/asset_pipeline_test.rb +0 -20
  196. data/test/rails/caching_test.rb +0 -456
  197. data/test/rails/cells_test.rb +0 -119
  198. data/test/rails/forms_test.rb +0 -75
  199. data/test/rails/integration_test.rb +0 -299
  200. data/test/rails/render_test.rb +0 -189
  201. data/test/rails/view_model_test.rb +0 -226
  202. data/test/rails/view_test.rb +0 -49
  203. data/test/rails_helper_api_test.rb +0 -58
  204. data/test/self_contained_test.rb +0 -31
data/Rakefile CHANGED
@@ -8,6 +8,6 @@ task :default => :test
8
8
 
9
9
  Rake::TestTask.new(:test) do |test|
10
10
  test.libs << 'test'
11
- test.test_files = FileList['test/*_test.rb', 'test/rails/*_test.rb']
11
+ test.pattern = 'test/*_test.rb'
12
12
  test.verbose = true
13
13
  end
data/TODO.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # 4.0
2
2
 
3
+ * Add tests for with_assets config
4
+
5
+
3
6
  * Get rid of the annoying `ActionController` dependency that needs to be passed into each cell. We only need it for "contextual links", when people wanna link to the same page. Make them pass in a URL generator object as a normal argument instead.
4
7
  * Generated cells will be view models per default.
5
8
  * Introduce Composition as in Reform, Representable, etc, when passing in a hash.
@@ -1,35 +1,26 @@
1
1
  lib = File.expand_path('../lib/', __FILE__)
2
2
  $:.unshift lib unless $:.include?(lib)
3
3
 
4
- require 'cells/version'
4
+ require 'cell/version'
5
5
 
6
- Gem::Specification.new do |s|
7
- s.name = "cells"
8
- s.version = Cells::VERSION
9
- s.platform = Gem::Platform::RUBY
10
- s.authors = ["Nick Sutterer"]
11
- s.email = ["apotonick@gmail.com"]
12
- s.homepage = "http://cells.rubyforge.org"
13
- s.summary = %q{View Components for Rails.}
14
- s.description = %q{Cells are view components for Rails. They are lightweight controllers, can be rendered in views and thus provide an elegant and fast way for encapsulation and component-orientation.}
15
- s.license = 'MIT'
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cells"
8
+ spec.version = Cell::VERSION::STRING
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["Nick Sutterer"]
11
+ spec.email = ["apotonick@gmail.com"]
12
+ spec.homepage = "https://github.com/apotonick/cells"
13
+ spec.summary = %q{View Models for Rails.}
14
+ spec.description = %q{Cells replace partials and helpers with OOP view models, giving you proper encapsulation, inheritance, testability and a cleaner view architecture.}
15
+ spec.license = 'MIT'
16
16
 
17
- s.files = `git ls-files`.split("\n")
18
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
- s.require_paths = ["lib"]
17
+ spec.files = `git ls-files`.split("\n")
18
+ spec.test_files = `git ls-files -- {test}/*`.split("\n")
19
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
21
 
22
- s.add_dependency "actionpack", ">= 3.0"
23
- s.add_dependency "railties", ">= 3.0"
24
- s.add_dependency "uber", "~> 0.0.8"
25
-
26
- s.add_development_dependency "rake"
27
- s.add_development_dependency "haml"
28
- s.add_development_dependency "slim"
29
- s.add_development_dependency "tzinfo" # FIXME: why the hell do we need this for 3.1?
30
- s.add_development_dependency "minitest", ">= 4.7.5"
31
- s.add_development_dependency "activemodel"
32
- s.add_development_dependency "capybara"
33
- s.add_development_dependency "sprockets"
34
- s.add_development_dependency "disposable", "~> 0.0.6"
22
+ spec.add_dependency 'actionpack', '>= 3.2'
23
+ spec.add_dependency "uber", "~> 0.0.9"
24
+ spec.add_dependency 'tilt', '>= 1.4', '< 3'
25
+ spec.add_dependency 'disposable', '~> 0.0.8'
35
26
  end
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "minitest-reporters"
6
+ gem "pry-byebug", :platforms => [:mri_20, :mri_21]
7
+ gem "appraisal"
8
+ gem "rake"
9
+ gem "test_xml"
10
+ gem "railties", :github => "rails/rails", :branch => "3-2-stable"
11
+ gem "tzinfo"
12
+ gem "minitest", "4.7.5"
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "minitest-reporters"
6
+ gem "pry-byebug", :platforms => [:mri_20, :mri_21]
7
+ gem "appraisal"
8
+ gem "rake"
9
+ gem "test_xml"
10
+ gem "railties", "4.0.12"
11
+ gem "activemodel"
12
+ gem "minitest", "4.7.5"
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,15 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "minitest-reporters"
6
+ gem "pry-byebug", :platforms => [:mri_20, :mri_21]
7
+ gem "appraisal"
8
+ gem "rake"
9
+ gem "test_xml"
10
+
11
+ gem "railties", "~> 4.1.0" #, :github => "rails/rails", :branch => "4-1-stable"
12
+ gem "activemodel", "~> 4.1.0" #, :github => "rails/rails", :branch => "4-1-stable"
13
+ gem "minitest", "~> 5.2"
14
+
15
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "minitest-reporters"
6
+ gem "pry-byebug", :platforms => [:mri_20, :mri_21]
7
+ gem "appraisal"
8
+ gem "rake"
9
+ gem "test_xml"
10
+ gem "railties", :github => "rails/rails", :branch => "4-2-stable"
11
+ gem "activemodel", :github => "rails/rails", :branch => "4-2-stable"
12
+ gem "minitest", "~> 5.2"
13
+
14
+ gemspec :path => "../"
@@ -1,27 +1,34 @@
1
+ require 'tilt'
2
+ require 'uber/inheritable_attr'
3
+ require 'uber/delegates'
4
+ require 'cell/version'
5
+ require 'active_support/dependencies/autoload'
6
+
1
7
  module Cell
2
- module OptionsConstructor
3
- private
4
- def process_args(options={})
5
- if options.is_a?(Hash) # TODO: i don't like this too much.
6
- process_options(options)
7
- else
8
- process_model(options)
9
- end
8
+ extend ActiveSupport::Autoload
10
9
 
11
- super # Base.
12
- end
10
+ autoload :Concept
11
+ autoload :TestCase
12
+ autoload :TestHelper
13
13
 
14
- # DISCUSS: have 2 classes for that?
14
+ def self.rails_version
15
+ Gem::Version.new(ActionPack::VERSION::STRING)
16
+ end
15
17
 
16
- def process_options(options)
17
- options.each do |k, v|
18
- instance_variable_set("@#{k}", v)
19
- singleton_class.class_eval { attr_reader k }
20
- end
18
+ class TemplateMissingError < RuntimeError
19
+ def initialize(base, prefixes, view, engine, formats)
20
+ super("Template missing: view: `#{view.to_s}.#{engine}` prefixes: #{prefixes.inspect} view_paths:#{base.inspect}")
21
21
  end
22
+ end # Error
23
+ end
22
24
 
23
- def process_model(model)
24
- @model = model
25
- end
26
- end
27
- end
25
+ require 'cell/caching'
26
+ require 'cell/caching/notification'
27
+ require 'uber/builder'
28
+ require 'cell/prefixes'
29
+ require 'cell/self_contained'
30
+ require 'cell/layout'
31
+ require 'cell/templates'
32
+ require 'cell/view_model'
33
+
34
+ require 'cell/railtie'
@@ -1,7 +1,6 @@
1
1
  require 'active_support/concern'
2
2
  require 'active_support/cache'
3
3
  require 'uber/options'
4
- require 'uber/inheritable_attr'
5
4
 
6
5
  module Cell
7
6
  module Caching
@@ -36,8 +35,8 @@ module Cell
36
35
  cache_store.delete(key, *args)
37
36
  end
38
37
 
39
-
40
38
  private
39
+
41
40
  def expand_cache_key(key)
42
41
  ::ActiveSupport::Cache.expand_cache_key(key, :cells)
43
42
  end
@@ -53,18 +52,20 @@ module Cell
53
52
  fetch_from_cache_for(key, options) { super(state, *args) }
54
53
  end
55
54
 
56
- def cache_configured?
57
- @cache_configured
55
+ def cache_store # we want to use DI to set a cache store in cell/rails.
56
+ ActionController::Base.cache_store
58
57
  end
59
- attr_writer :cache_configured
60
-
61
- attr_accessor :cache_store # we want to use DI to set a cache store in cell/rails.
62
58
 
63
59
  def cache?(state, *args)
64
- cache_configured? and state_cached?(state) and self.class.conditional_procs[state].evaluate(self, *args)
60
+ perform_caching? and state_cached?(state) and self.class.conditional_procs[state].evaluate(self, *args)
65
61
  end
66
62
 
67
63
  private
64
+
65
+ def perform_caching?
66
+ ActionController::Base.perform_caching
67
+ end
68
+
68
69
  def fetch_from_cache_for(key, options)
69
70
  cache_store.fetch(key, options) do
70
71
  yield
@@ -74,18 +75,5 @@ module Cell
74
75
  def state_cached?(state)
75
76
  self.class.version_procs.has_key?(state)
76
77
  end
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
78
+ end
91
79
  end
@@ -0,0 +1,15 @@
1
+ module Cell
2
+ module Caching
3
+ module Notifications
4
+ def fetch_from_cache_for(key, options)
5
+ ActiveSupport::Notifications.instrument('read_fragment.cells', :key => key) do
6
+ cache_store.fetch(key, options) do
7
+ ActiveSupport::Notifications.instrument('write_fragment.cells', :key => key) do
8
+ yield
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,19 +1,15 @@
1
- # TODO: deprecate parent_controller, ViewModel
2
1
  class Cell::Concept < Cell::ViewModel
3
2
  abstract!
4
- self.view_paths = "app/concepts"
3
+ self.view_paths = ["app/concepts"]
5
4
 
6
5
  # TODO: this should be in Helper or something. this should be the only entry point from controller/view.
7
6
  class << self
8
- def cell_for(name, controller, *args)
9
- Cell::Builder.new(name.classify.constantize, controller).call(controller, *args)
7
+ def class_from_cell_name(name)
8
+ name.classify.constantize
10
9
  end
11
10
 
12
11
  def controller_path
13
- # TODO: cache on class level
14
- # DISCUSS: only works with trailblazer style directories. this is a bit risky but i like it.
15
- # applies to Comment::Cell, Comment::Cell::Form, etc.
16
- name.sub(/::Cell/, '').underscore unless anonymous?
12
+ @controller_path ||= name.sub(/::Cell/, '').underscore
17
13
  end
18
14
  end
19
15
 
@@ -22,65 +18,4 @@ class Cell::Concept < Cell::ViewModel
22
18
  end
23
19
 
24
20
  self_contained!
25
-
26
- # DISCUSS: experimental, allows to render layouts from the partial view directory instead of a global one.
27
- module Rendering
28
- def view_renderer
29
- @_view_renderer ||= Renderer.new(lookup_context)
30
- end
31
-
32
- if Cell.rails_version >= 3.2
33
- def _normalize_layout(value) # 3.2+
34
- value
35
- end
36
- else
37
- def _normalize_options(options) # FIXME: for rails 3.1, only. in 3.2+ it's _normalize_layout.
38
- super
39
-
40
- if options[:layout]
41
- options[:layout].sub!("layouts/", "")
42
- end
43
- end
44
- end
45
- end
46
-
47
- class Renderer < ActionView::Renderer
48
- def render_template(context, options) # Rails 4.0 # FIXME: make that simpler to override in rails core.
49
- TemplateRenderer.new(@lookup_context).render(context, options)
50
- end
51
-
52
- def _template_renderer # Rails 3.x
53
- @_template_renderer ||= TemplateRenderer.new(@lookup_context)
54
- end
55
-
56
-
57
- class TemplateRenderer < ActionView::TemplateRenderer
58
- def render(context, options)
59
- @options = options
60
- super
61
- end
62
-
63
- def find_layout(layout, keys)
64
- resolve_layout(layout, keys, [formats.first])
65
- end
66
-
67
- def resolve_layout(layout, keys, formats)
68
- details = @details ? @details.dup : {} # FIXME: provide the entire Renderer layer here. this is to make it compatible with Rails 3.1.
69
- details[:formats] = formats
70
-
71
- case layout
72
- when String
73
- find_args = [layout, @options[:prefixes], false, keys, details]
74
- find_args = [layout, @options[:prefixes], false, keys] if Cell.rails_version.~ 3.1
75
- find_template(*find_args)
76
- when Proc
77
- resolve_layout(layout.call, keys, formats)
78
- else
79
- layout
80
- end
81
- end
82
- end
83
- end # Rendering
84
-
85
- include Rendering
86
21
  end
@@ -0,0 +1,11 @@
1
+ module Cell
2
+ module Development
3
+ def self.included(base)
4
+ base.instance_eval do
5
+ def templates
6
+ Templates.new
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
- module Cells
1
+ module Cell
2
2
  # Now <tt>Rails::Engine</tt>s can contribute to Cells view paths.
3
3
  # By default, any 'app/cells' found inside any Engine is automatically included into Cells view paths.
4
4
  #
@@ -0,0 +1,20 @@
1
+ module Cell
2
+ # Set the layout per cell class. This is used in #render calls. Gets inherited to subclasses.
3
+ module Layout
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.inheritable_attr :layout_name
7
+ end
8
+
9
+ module ClassMethods
10
+ def layout(name)
11
+ self.layout_name = name
12
+ end
13
+ end
14
+
15
+ def process_options!(options)
16
+ options[:layout] ||= self.class.layout_name
17
+ super
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ # Allows to render global partials, for example.
2
+ #
3
+ # render partial: "../views/shared/container"
4
+ module Cell::ViewModel::Partial
5
+ def process_options!(options)
6
+ super
7
+ return unless partial = options[:partial]
8
+
9
+ parts = partial.split("/")
10
+ view = parts.pop
11
+ view = "_#{view}"
12
+ view += ".#{options[:formats].first}" if options[:formats]
13
+ prefixes = [parts.join("/")]
14
+
15
+ options.merge!(:view => view, :prefixes => prefixes)
16
+ end
17
+ end
@@ -1,6 +1,6 @@
1
1
  # TODO: merge into Rails core.
2
2
  # TODO: cache _prefixes on class layer.
3
- module Cell::Base::Prefixes
3
+ module Cell::Prefixes
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  def _prefixes
@@ -1,64 +1,72 @@
1
- require 'cell/rack'
2
-
1
+ # These Methods are automatically added to all Controllers and Views when
2
+ # the cells plugin is loaded.
3
3
  module Cell
4
- class Rails < Rack
5
- # When this file is included we can savely assume that a rails environment with caching, etc. is available.
6
- include ActionController::RequestForgeryProtection
7
-
8
- abstract!
9
- delegate :session, :params, :request, :config, :env, :url_options, :to => :parent_controller
10
-
11
- class Builder < Cell::Builder
12
- def run_builder_block(block, controller, *args)
13
- super(block, *args)
14
- end
15
- end
16
-
17
- class << self
18
- def cache_store
19
- # FIXME: i'd love to have an initializer in the cells gem that _sets_ the cache_store attr instead of overriding here.
20
- # since i dunno how to do that we'll have this method in rails for now.
21
- # DISCUSS: should this be in Cell::Rails::Caching ?
22
- ActionController::Base.cache_store
4
+ module RailsExtensions
5
+ module ActionController
6
+ def cell(name, *args, &block)
7
+ ViewModel.cell(name, self, *args, &block)
23
8
  end
24
9
 
25
- def expire_cache_key(key, *args) # FIXME: move to Rails.
26
- expire_cache_key_for(key, cache_store ,*args)
10
+ def concept(name, *args, &block)
11
+ Concept.cell(name, self, *args, &block)
27
12
  end
28
13
 
29
- # Main entry point for instantiating cells.
14
+ # # Renders the cell state and returns the content. You may pass options here, too. They will be
15
+ # # around in @opts.
16
+ # #
17
+ # # Example:
18
+ # #
19
+ # # @box = render_cell(:posts, :latest, :user => current_user)
20
+ # #
21
+ # # If you need the cell instance before it renders, you can pass a block receiving the cell.
22
+ # #
23
+ # # Example:
24
+ # #
25
+ # # @box = render_cell(:comments, :top5) do |cell|
26
+ # # cell.markdown! if config.parse_comments?
27
+ # # end
28
+ # def render_cell(name, state, *args, &block)
29
+ # ::Cell::Rails.render_cell(name, state, self, *args, &block)
30
+ # end
30
31
 
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.
34
- end
32
+ # # Expires the cached cell state view, similar to ActionController::expire_fragment.
33
+ # # Usually, this method is used in Sweepers.
34
+ # # Beside the obvious first two args <tt>cell_name</tt> and <tt>state</tt> you can pass
35
+ # # in additional cache key <tt>args</tt> and cache store specific <tt>opts</tt>.
36
+ # #
37
+ # # Example:
38
+ # #
39
+ # # class ListSweeper < ActionController::Caching::Sweeper
40
+ # # observe List, Item
41
+ # #
42
+ # # def after_save(record)
43
+ # # expire_cell_state :my_listing, :display_list
44
+ # # end
45
+ # #
46
+ # # will expire the view for state <tt>:display_list</tt> in the cell <tt>MyListingCell</tt>.
47
+ # def expire_cell_state(cell_class, state, args={}, opts=nil)
48
+ # key = cell_class.state_cache_key(state, args)
49
+ # cell_class.expire_cache_key(key, opts)
50
+ # end
35
51
  end
36
52
 
53
+ module ActionView
54
+ # Returns the cell instance for +name+. You may pass arbitrary options to your
55
+ # cell.
56
+ #
57
+ # = cell(:song, :title => "Creeping Out Sara").render(:show)
58
+ def cell(name, *args, &block)
59
+ controller.cell(name, *args, &block)
60
+ end
37
61
 
38
- attr_reader :parent_controller
39
- alias_method :controller, :parent_controller
40
-
41
- def initialize(parent_controller, *args)
42
- super(parent_controller, *args) # FIXME: huh?
43
- @parent_controller = parent_controller
44
- end
45
-
46
- def cache_configured?
47
- ActionController::Base.send(:cache_configured?) # DISCUSS: why is it private?
48
- end
49
-
50
- def cache_store
51
- self.class.cache_store # in Rails, we have a global cache store.
52
- end
62
+ # # See Cells::Rails::ActionController#render_cell.
63
+ # def render_cell(name, state, *args, &block)
64
+ # ::Cell::Rails.render_cell(name, state, controller, *args, &block)
65
+ # end
53
66
 
54
- module DSL
55
- def cell(name, *args)
56
- # TODO: this method should be an instance method everywhere.
57
- Base.cell_for(name, parent_controller, *args)
67
+ def concept(name, *args, &block)
68
+ controller.concept(name, *args, &block)
58
69
  end
59
70
  end
60
- include DSL
61
71
  end
62
72
  end
63
-
64
- require "cell/rails/view_model" # TODO: remove in 4.0.