cells 4.0.0.beta6 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5c2400e9d14760d1546557317bc9e98f97bb3b7
4
- data.tar.gz: 4d7de6cd09957c5c12b7bd8b7030ebb119d5c5d5
3
+ metadata.gz: 6c08042fbea7ac33f3607605e1e290c0956b4312
4
+ data.tar.gz: 017db4d48f5a0eaab84f4ecb8fc014b9470f21f0
5
5
  SHA512:
6
- metadata.gz: 2cc1c784ecb8a5e5838650b1e31beac41a03c92d5df45205b7811342d6acaba8a5a4dabeabf8eb752bfa0480fa784bda88a914e08ee14de9ce0ba7d7d7d8d123
7
- data.tar.gz: a9c00ab7bcb2ab01132202756e1227cf50a6a976e3de7d69e9d9c74960874b7e910403cec640b12b63665e641acb850e0be3382a2d641d986f11b7b47e2dbef3
6
+ metadata.gz: 841380b7a18d52879c7f0323816cf78bec726d520478c55a52d8366fc9706974440572e96a1fa6298daa4a056c22f720a359c1e637a2df2c6547f40c3c34c021
7
+ data.tar.gz: da654a5b2dceec48cab59f4b89f3c40a9e2b326bc92d0040d1ccbcac0361ec91b7756501fd21dfdb612484b1453fde248925772cf3771eed61bc26ec083441d3
data/CHANGES.md CHANGED
@@ -18,6 +18,10 @@
18
18
 
19
19
  * When using HAML, we do not use any of HAML's helper hacks to "fix" ActionView and XSS. While you might not note this, it removes tons of code from our stack.
20
20
 
21
+ ## 4.0.0.rc1
22
+
23
+ * Move delegations of `#url_options` etc. to the railtie, which makes it work.
24
+
21
25
  ## 4.0.0.beta6
22
26
 
23
27
  * Removed `ViewModel::template_engine`. This is now done explicitly by including `Cell::Erb`, etc. and happens automatically in a Rails environment.
data/README.md CHANGED
@@ -1,64 +1,87 @@
1
1
  # Cells
2
2
 
3
- *View Components for Rails.*
4
-
3
+ *View Components for Ruby and Rails.*
5
4
 
6
5
  ## Overview
7
6
 
8
- Cells allow you to encapsulate parts of your page into separate MVC components. These components are called _view models_.
7
+ Cells allow you to encapsulate parts of your UI into components into _view models_. View models, or cells, are simple ruby classes that can render templates.
9
8
 
10
- You can render view models anywhere in your code. Mostly, cells are used in views to replace a helper/partial/filter mess, as a mailer renderer substitute or they get hooked to routes to completely bypass `ActionController`.
9
+ Nevertheless, a cell gives you more than just a template renderer. They allow proper OOP, polymorphic builders, nesting, view inheritance, using Rails helpers, [asset packaging](http://trailblazerb.org/gems/cells/rails.html#asset-pipeline) to bundle JS, CSS or images, simple distribution via gems or Rails engines, encapsulated testing, [caching](#caching), and [integrate with Trailblazer](#concept-cells).
11
10
 
12
- As you have already noticed we use _cell_ and _view model_ interchangeably here.
11
+ ## This is not Cells 3.x!
13
12
 
13
+ Temporary note: This is the README and API for Cells 4. Many things have improved. If you want to upgrade, [follow this guide](https://github.com/apotonick/cells/wiki/From-Cells-3-to-Cells-4---Upgrading-Guide). When in trouble, join us on the IRC (Freenode) #trailblazer channel.
14
14
 
15
- ## The Book
16
15
 
17
- Cells is part of the [Trailblazer project](https://github.com/apotonick/trailblazer). Please [buy my book](https://leanpub.com/trailblazer) to support the development and to learn all the cool stuff about Cells. The book discusses the following.
16
+ ## Rendering Cells
18
17
 
19
- <a href="https://leanpub.com/trailblazer">
20
- ![](https://raw.githubusercontent.com/apotonick/trailblazer/master/doc/trb.jpg)
21
- </a>
18
+ You can render cells anywhere and as many as you want, in views, controllers, composites, mailers, etc.
22
19
 
23
- * Basic view models, replacing helpers, and how to structure your view into cell components (chapter 2 and 4).
24
- * Advanced Cells API (chapter 4 and 6).
25
- * Testing Cells (chapter 4 and 6).
26
- * Cells Pagination with AJAX (chapter 6).
27
- * View Caching and Expiring (chapter 7).
20
+ Rendering a cell in Rails ironically happens via a helper.
28
21
 
29
- More chapters are coming.
22
+ ```ruby
23
+ <%= cell(:comment, @comment) %>
24
+ ```
30
25
 
31
- The book picks up where the README leaves off. Go grab a copy and support us - it talks about object- and view design and covers all aspects of the API.
26
+ This boils down to the following invocation, that can be used to render cells in *any other Ruby* environment.
32
27
 
33
- ## No ActionView
28
+ ```ruby
29
+ CommentCell.(@comment).()
30
+ ```
34
31
 
35
- Starting with Cells 4.0 we no longer use `ActionView` as a template engine. Removing this jurassic dependency cuts down Cells' rendering code to less than 50 lines and improves rendering speed by 300%!
32
+ In Rails you have the same helper API for views and controllers.
36
33
 
37
- **Note for Cells 3.x:** This README only documents Cells 4.0. Please [read the old README if you're using Cells 3.x](https://github.com/apotonick/cells/tree/31f6ed82b87b3f92613698442fae6fd61cc16de9#cells).
34
+ ```ruby
35
+ class DasboardController < ApplicationController
36
+ def dashboard
37
+ @comments = cell(:comment, Comment.recent).()
38
+ @traffic = cell(:report, TrafficReport.find(1))
39
+ end
40
+ ```
38
41
 
42
+ Usually, you'd pass in one or more objects you want the cell to present. That can be an ActiveRecord model, a ROM instance or any kind of PORO you fancy.
39
43
 
40
- ## Installation
44
+ ## Cell Class
41
45
 
42
- Cells run with all Rails >= 3.2. Lower versions of Rails will still run with Cells, but you will get in trouble with the helpers.
46
+ A cell is a light-weight class with one or multiple methods that render views.
43
47
 
44
48
  ```ruby
45
- gem 'cells', "~> 4.0.0"
49
+ class Comment::Cell < Cell::ViewModel
50
+ property :body
51
+ property :author
52
+
53
+ def show
54
+ render
55
+ end
56
+
57
+ private
58
+ def author_link
59
+ link_to "#{author.email}", author
60
+ end
61
+ end
46
62
  ```
47
63
 
48
- ## Prerequisites
64
+ Here, `show` is the only public method. By calling `render` it will invoke rendering for the `show` view.
49
65
 
50
- Cells comes bundled with ERB support. To render HAML, you have to include the [cells-haml](https://github.com/trailblazer/cells-haml) gem. The same for [cells-slim](https://github.com/trailblazer/cells-slim). Currently, they are only available as github dependencies, they will be released soon (early 2015).
51
66
 
52
- ```ruby
53
- gem "cells-haml", github: 'trailblazer/cells-haml'
67
+ ## Logicless Views
68
+
69
+ Views come packaged with the cell and can be ERB, Haml, or Slim.
70
+
71
+ ```erb
72
+ <h3>New Comment</h3>
73
+ <%= body %>
74
+
75
+ By <%= author_link %>
54
76
  ```
55
77
 
56
- The template engine extensions fix severe bugs in combination with Rails helpers and the respective engine. Time will tell if we can convince the template teams to merge these fixes.
78
+ The concept of "helpers" that get strangely copied from modules to the view does not exist in Cells anymore.
57
79
 
80
+ Methods called in the view are directly called _on the cell instance_. You're free to use loops and deciders in views, even instance variables are allowed, but Cells tries to push you gently towards method invocations to access data in the view.
58
81
 
59
- ## File Layout
82
+ ## File Structure
60
83
 
61
- Cells are placed in `app/cells`.
84
+ In Rails, cells are placed in `app/cells` or `app/concepts/`. Every cell has their own directory where it keeps views, assets and code.
62
85
 
63
86
  ```
64
87
  app
@@ -69,100 +92,321 @@ app
69
92
  │ │ ├── list.haml
70
93
  ```
71
94
 
95
+ The discussed `show` view would reside in `app/cells/comment/show.haml`. However, you can set [any set of view paths](#view-paths) you want.
72
96
 
73
- ## Generate
74
97
 
75
- Use the bundled generator to set up a cell.
98
+ ## Invocation Styles
76
99
 
77
- ```shell
78
- rails generate cell comment
100
+ In order to make a cell render, you have to call the rendering methods. While you could call the method directly, the prefered way is the _call style_.
101
+
102
+ ```ruby
103
+ cell(:comment, @song).() # calls CommentCell#show.
104
+ cell(:comment, @song).(:index) # calls CommentCell#index.
79
105
  ```
80
106
 
107
+ The call style respects caching.
108
+
109
+ Keep in mind that `cell(..)` really gives you the cell object. In case you want to reuse the cell, need setup logic, etc. that's completely up to you.
110
+
111
+ ## Parameters
112
+
113
+ You can pass in as many parameters as you need. Per convention, this is a hash.
114
+
115
+ ```ruby
116
+ cell(:comment, @song, volume: 99, genre: "Jazz Fusion")
81
117
  ```
82
- create app/cells/
83
- create app/cells/comment
84
- create app/cells/comment_cell.rb
85
- create app/cells/comment/show.erb
118
+
119
+ Options can be accessed via the `@options` instance variable.
120
+
121
+ Naturally, you may also pass arbitrary options into the call itself. Those will be simple method arguments.
122
+
123
+ ```ruby
124
+ cell(:comment, @song).(:show, volume: 99)
86
125
  ```
87
126
 
127
+ Then, the `show` method signature changes to `def show(options)`.
128
+
88
129
 
89
- ## Rendering View Models
130
+ ## Testing
90
131
 
91
- Suppose we are to render a "partial" for `Comment` model
132
+ A huge benefit from "all this encapsulation" is that you can easily write tests for your components. The API does not change and everything is exactly as it would be in production.
92
133
 
93
134
  ```ruby
94
- @comment = Comment.find(1)
135
+ html = CommentCell.(@comment).()
136
+ Capybara.string(html).must_have_css "h3"
95
137
  ```
96
138
 
97
- Cells brings you one helper method `#cell` to be used in your controller views or layouts.
139
+ It is completely up to you how you test, whether it's RSpec, MiniTest or whatever. All the cell does is return HTML.
98
140
 
99
- ```haml
100
- = cell(:comment, @comment)
141
+ [In Rails, there's support](http://trailblazerb.org/gems/cells/testing.html) for TestUnit, MiniTest and RSpec available, along with Capybara integration.
142
+
143
+ ## Installation
144
+
145
+ Cells run with all Rails >= 4.0. Lower versions of Rails will still run with Cells, but you will get in trouble with the helpers.
146
+
147
+ ```ruby
148
+ gem 'cells', "~> 4.0.0"
101
149
  ```
102
150
 
103
- This is the short form of rendering a cell. Simple, isn't it?
151
+ (Note: we use Cells in production with Rails 3.2 and Haml and it works great.)
104
152
 
105
- Note that a view model _always_ requires a model in the constructor (or a composition). This doesn't have to be an `ActiveRecord` object but can be any type of Ruby object you want to present.
153
+ Various template engines are supported but need to be added to your Gemfile.
106
154
 
107
- To understand invoking cells, here's the long form of it.
155
+ * [cells-erb](https://github.com/trailblazer/cells-erb)
156
+ * [cells-haml](https://github.com/trailblazer/cells-haml)
157
+ * [cells-slim](https://github.com/trailblazer/cells-slim)
108
158
 
109
- ```haml
110
- = cell(:comment, @comment).call(:show)
159
+ ```ruby
160
+ gem "cells-erb"
161
+ ```
162
+
163
+ In Rails, this is all you need to do. In other environments, you need to include the respective module into your cells.
164
+
165
+ ```ruby
166
+ class CommentCell < Cell::ViewModel
167
+ include ::Cell::Erb # or Cell::Haml, or Cell::Slim
168
+ end
169
+ ```
170
+
171
+ ## Concept Cells
172
+
173
+ To have real self-contained cells you should use the new _concept cell_ which follows the [Trailblazer](http://trailblazerb.org) naming style. Concept cells need to be derived from `Cell::Concept`, sit in a namespace and are usually named `Cell`.
174
+
175
+ ```ruby
176
+ class Comment::Cell < Cell::Concept
177
+ # ..
178
+ end
179
+ ```
180
+
181
+ Their directory structure looks as follows.
182
+
183
+ ```
184
+ app
185
+ ├── concepts
186
+ │ ├── comment
187
+ │ │ ├── cell.rb
188
+ │ │ ├── views
189
+ │ │ │ ├── show.haml
190
+ ```
191
+
192
+ This integrates with Trailblazer where classes for one _concept_ sit in the same directory. Please [read the book](http://leanpub.com/trailblazer) to learn how to use cells with Trailblazer.
193
+
194
+ Concept cells are rendered using the `concept` helper.
195
+
196
+ ```erb
197
+ <%= concept("comment/cell", @comment) %>
198
+ ```
199
+
200
+ Other than that, normal cells and concept cells are identical.
201
+
202
+ ## Namespaces
203
+
204
+ Cells can be namespaced as well. This is used for [concept cells](#concept-cells), too.
205
+
206
+ ```ruby
207
+ module Admin
208
+ class CommentCell < Cell::ViewModel
111
209
  ```
112
210
 
113
- 1. `#cell(..)` simply returns the cell instance. You can do whatever you want with it.
114
- 2. `.call(:show)` will invoke the `#show` method respecting caching settings.
211
+ Invocation in Rails would happen as follows.
212
+
213
+ ```ruby
214
+ cell("admin/comment", @comment).()
215
+ ```
115
216
 
116
- When rendering cells in views, you can skip the `call` part as this is implicitely done by the template.
217
+ Views will be searched in `app/cells/admin/comment` per default.
117
218
 
118
- Please [refer to the docs](#invocation-styles) for different ways of invoking view models.
119
219
 
220
+ ## Rails Helper API
120
221
 
121
- ## View Model Classes
222
+ Even in a non-Rails environment, Cells provides the Rails view API and allows using all Rails helpers.
122
223
 
123
- A view model is always implemented as a class. This gives you encapsulation, proper inheritance and namespacing out-of-the-box.
224
+ You have to include all helper modules into your cell class. You can then use `link_to`, `simple_form_for` or whatever you feel like.
124
225
 
125
226
  ```ruby
126
227
  class CommentCell < Cell::ViewModel
127
- def show
128
- render
228
+ include ActionView::Helpers::UrlHelper
229
+ include ActionView::Helpers::CaptureHelper
230
+
231
+ def author_link
232
+ content_tag :div, link_to(author.name, author)
129
233
  end
234
+ ```
235
+
236
+ As always, you can use helpers in cells and in views.
237
+
238
+ You might run into problems with wrong escaping or missing URL helpers. This is not Cells' fault but Rails suboptimal way of implementing and interfacing their helpers. Please open the actionview gem helper code and try figuring out the problem yourself before bombarding us with issues because helper `xyz` doesn't work.
239
+
240
+
241
+ ## View Paths
242
+
243
+ In Rails, the view path is automatically set to `app/cells/` or `app/concepts/`. You can append or set view paths by using `::view_paths`. Of course, this works in any Ruby environment.
244
+
245
+ ```ruby
246
+ class CommentCell < Cell::ViewModel
247
+ self.view_paths = "lib/views"
130
248
  end
131
249
  ```
132
250
 
133
- Calling `#render` will render the cell's `show.haml` template, located in `app/cells/comment`. Invoking `render` is explicit: this means, it really returns the rendered view string, allowing you to modify the HTML afterwards.
251
+ ## Asset Packaging
252
+
253
+ Cells can easily ship with their own JavaScript, CSS and more and be part of Rails' asset pipeline. Bundling assets into a cell allows you to implement super encapsulated widgets that are stand-alone. Asset pipeline is [documented here](http://trailblazerb.org/gems/cells/rails.html#asset-pipeline).
254
+
255
+ ## Render API
256
+
257
+ ## Nested Cells
258
+
259
+ Cells love to render. You can render as many views as you need in a cell state or view.
260
+
261
+ ```ruby
262
+ <%= render :index %>
263
+ ```
264
+
265
+ The `#render` method really just returns the rendered template string, allowing you all kind of modification.
134
266
 
135
267
  ```ruby
136
268
  def show
137
- "<div>" + render + "</div>"
269
+ render + render(:additional)
138
270
  end
139
271
  ```
140
272
 
141
- ## Views In Theory
273
+ You can even render other cells _within_ a cell using the exact same API.
142
274
 
143
- In Cells, we don't distinguish between _view_ or _partial_. Every view you render is a partial, every partial a view. You can render views inside views, compose complex UI blocks with multiple templates and go crazy. This is what cells _views_ are made for.
275
+ ```ruby
276
+ def about
277
+ cell(:profile, model.author).()
278
+ end
279
+ ```
144
280
 
145
- Cells supports all template engines that are supported by the excellent [tilt](https://github.com/rtomayko/tilt) gem - namely, this is ERB, HAML, Slim, and many more.
281
+ This works both in cell views and on the instance, in states.
146
282
 
147
- In these examples, we're using HAML.
148
283
 
149
- BTW, Cells doesn't include the format into the view name. 99% of all cells render HTML anyway, so we prefer short names like `show.haml`.
284
+ ## Collections
285
+
286
+ In order to render collections, Cells comes with a shortcut.
150
287
 
288
+ ```ruby
289
+ comments = Comment.all #=> three comments.
290
+ cell(:comment, collection: comments)
291
+ ```
151
292
 
152
- ## Views In Practice
293
+ This will invoke `cell(:comment, song).()` three times and concatenate the rendered output automatically. In case you don't want `show` but another state rendered, use `:method`.
153
294
 
154
- Let's check out the `show.haml` view to see how they work.
295
+ ```ruby
296
+ cell(:comment, collection: comments, method: :list)
297
+ ```
155
298
 
156
- ```haml
157
- -# app/cells/comment/show.haml
299
+ Note that you _don't_ need to invoke call here, the `:collection` behavior internally handles that for you.
158
300
 
159
- %h1 Comment
301
+ Additional options are passed to every cell constructor.
160
302
 
161
- = model.body
162
- By
163
- = link_to model.author.name, model.author
303
+ ```ruby
304
+ cell(:comment, collection: comments, style: "awesome", volume: "loud")
164
305
  ```
165
306
 
307
+ ## Caching
308
+
309
+ For every cell class you can define caching per state. Without any configuration the cell will run and render the state once. In following invocations, the cached fragment is returned.
310
+
311
+ ```ruby
312
+ class CommentCell < Cell::ViewModel
313
+ cache :show
314
+
315
+ # ..
316
+ end
317
+ ```
318
+
319
+ The `::cache` method will forward options to the caching engine.
320
+
321
+ ```ruby
322
+ cache :show, expires_in: 10.minutes
323
+ ```
324
+
325
+ You can also compute your own cache key, use dynamic keys, cache tags, and so on.
326
+
327
+ ```ruby
328
+ cache :show { |model, options| "comment/#{model.id}/#{model.updated_at}" }
329
+ cache :show, :if => lambda { |*| has_changed? }
330
+ cache :show, :tags: lambda { |model, options| "comment-#{model.id}" }
331
+ ```
332
+
333
+ Caching is documented [here](http://trailblazerb.org/gems/cells/caching.html) and in chapter 8 of the [Trailblazer book](http://leanpub.com/trailblazer).
334
+
335
+
336
+ ---------------------------------------
337
+
338
+ This is available via the `model` method. Declarative `::property`s give you readers to the model.
339
+
340
+
341
+ Cells allow you to encapsulate parts of your page into separate MVC components. These components are called _view models_.
342
+
343
+ You can render view models anywhere in your code. Mostly, cells are used in views to replace a helper/partial/filter mess, as a mailer renderer substitute or they get hooked to routes to completely bypass `ActionController`.
344
+
345
+ As you have already noticed we use _cell_ and _view model_ interchangeably here.
346
+
347
+
348
+ ## The Book
349
+
350
+ Cells is part of the [Trailblazer project](https://github.com/apotonick/trailblazer). Please [buy my book](https://leanpub.com/trailblazer) to support the development and to learn all the cool stuff about Cells. The book discusses the following.
351
+
352
+ <a href="https://leanpub.com/trailblazer">
353
+ ![](https://raw.githubusercontent.com/apotonick/trailblazer/master/doc/trb.jpg)
354
+ </a>
355
+
356
+ * Basic view models, replacing helpers, and how to structure your view into cell components (chapter 2 and 4).
357
+ * Advanced Cells API (chapter 4 and 6).
358
+ * Testing Cells (chapter 4 and 6).
359
+ * Cells Pagination with AJAX (chapter 6).
360
+ * View Caching and Expiring (chapter 7).
361
+
362
+ More chapters are coming.
363
+
364
+ The book picks up where the README leaves off. Go grab a copy and support us - it talks about object- and view design and covers all aspects of the API.
365
+
366
+ ## No ActionView
367
+
368
+ Starting with Cells 4.0 we no longer use `ActionView` as a template engine. Removing this jurassic dependency cuts down Cells' rendering code to less than 50 lines and improves rendering speed by 300%!
369
+
370
+ **Note for Cells 3.x:** This README only documents Cells 4.0. Please [read the old README if you're using Cells 3.x](https://github.com/apotonick/cells/tree/31f6ed82b87b3f92613698442fae6fd61cc16de9#cells).
371
+
372
+
373
+ ## Installation
374
+
375
+ Cells run with all Rails >= 3.2. Lower versions of Rails will still run with Cells, but you will get in trouble with the helpers.
376
+
377
+ ```ruby
378
+ gem 'cells', "~> 4.0.0"
379
+ ```
380
+
381
+ ## Prerequisites
382
+
383
+ Cells comes bundled with ERB support. To render HAML, you have to include the [cells-haml](https://github.com/trailblazer/cells-haml) gem. The same for [cells-slim](https://github.com/trailblazer/cells-slim). Currently, they are only available as github dependencies, they will be released soon (early 2015).
384
+
385
+ ```ruby
386
+ gem "cells-haml", github: 'trailblazer/cells-haml'
387
+ ```
388
+
389
+ The template engine extensions fix severe bugs in combination with Rails helpers and the respective engine. Time will tell if we can convince the template teams to merge these fixes.
390
+
391
+
392
+
393
+ ## Generate
394
+
395
+ Use the bundled generator to set up a cell.
396
+
397
+ ```shell
398
+ rails generate cell comment
399
+ ```
400
+
401
+ ```
402
+ create app/cells/
403
+ create app/cells/comment
404
+ create app/cells/comment_cell.rb
405
+ create app/cells/comment/show.erb
406
+ ```
407
+
408
+
409
+
166
410
  Cells provides you the view _model_ via the `#model` method. Here, this returns the `Comment` instance passed into the constructor.
167
411
 
168
412
  Of course, this view is a mess and needs be get cleaned up!
@@ -243,67 +487,9 @@ template_engine
243
487
  view_paths
244
488
 
245
489
 
246
- ## Invocation styles
247
-
248
- The explicit, long form allows you rendering cells in views, in controllers, mailers, etc.
249
-
250
- ```ruby
251
- cell(:comment, @comment).call(:show)
252
- ```
253
-
254
- As `:show` is the default action, you don't have to specify it.
255
-
256
- ```ruby
257
- cell(:comment, @comment).call
258
- ```
259
490
 
260
- In views, the template engine will automatically call `cell.to_s`. It does that for every object passed in as a placeholder. `ViewModel#to_s` exists and is aliased to `#call`, which allows to omit that part in a view.
261
491
 
262
- ```haml
263
- = cell(:comment, @comment)
264
- ```
265
492
 
266
- If you want, you can also call public methods directly on your cell. Note that this does _not_ respect caching, though.
267
-
268
- ```haml
269
- = cell(:comment, @comment).avatar
270
- ```
271
-
272
- ## Passing Options
273
-
274
- There's several ways to inject additional state into your cell.
275
-
276
- ### Object Style
277
-
278
- Cells can receive any set of options you need. Usually, a hash containing additional options is passed as the last argument.
279
-
280
- ```ruby
281
- cell(:comment, @comment, layout: :fancy)
282
- ```
283
-
284
- The third argument is accessable via `#options` in the instance.
285
-
286
- ```ruby
287
- def show
288
- render layout: options[:layout]
289
- end
290
- ```
291
-
292
- ### Functional Style
293
-
294
- You can also pass options to the action method itself, making your cell a bit more functional with less state.
295
-
296
- ```ruby
297
- cell(:comment, @comment).call(:show, layout: :fancy)
298
- ```
299
-
300
- Make sure the method is ready to process those arguments.
301
-
302
- ```ruby
303
- def show(layout=:default)
304
- render layout: layout
305
- end
306
- ```
307
493
 
308
494
  ## Collections
309
495
 
@@ -369,42 +555,6 @@ Multiple calls to `::builds` will be ORed. If no block returns a class, the orig
369
555
 
370
556
 
371
557
 
372
- # TODO: merge stuff below!
373
-
374
- ## File Structure
375
-
376
- In Cells 3.10 we introduce a new _optional_ file structure integrating with [Trailblazer](https://github.com/apotonick/trailblazer)'s "concept-oriented" layout.
377
-
378
- This new file layout makes a cell fully **self-contained** so it can be moved around just by grabbing one single directory.
379
-
380
- Activate it with
381
-
382
- ```ruby
383
- class Comment::Cell
384
- self_contained!
385
-
386
- # ...
387
- end
388
- ```
389
-
390
- Now, the cell directory ideally looks like the following.
391
-
392
- ```
393
- app
394
- ├── cells
395
- │ ├── comment
396
- │ │ ├── cell.rb
397
- │ │ ├── views
398
- │ │ │ ├── show.haml
399
- │ │ │ ├── list.haml
400
- ```
401
-
402
-
403
- Here, cell class and associated views are in the same self-contained `comment` directory.
404
-
405
- You can use the new views directory along with leaving your cell _class_ at `app/cells/comment_cell.rb`, if you fancy that.
406
-
407
-
408
558
  ## Asset Pipeline
409
559
 
410
560
  Cells can also package their own assets like JavaScript, CoffeeScript, Sass and stylesheets. When configured, those files go directly into Rails' asset pipeline. This is a great way to clean up your assets by pushing scripts and styles into the component they belong to. It makes it so much easier to find out which files are actually involved per "widget".
@@ -481,156 +631,7 @@ class Comment::FormCell < Cell::Rails
481
631
  When rendering views in `FormCell`, the view directories to look for templates will be inherited.
482
632
 
483
633
 
484
- ## Caching
485
-
486
- Cells allow you to cache per state. It's simple: the rendered result of a state method is cached and expired as you configure it.
487
-
488
- To cache forever, don't configure anything
489
-
490
- ```ruby
491
- class CartCell < Cell::Rails
492
- cache :show
493
-
494
- def show
495
- render
496
- end
497
- ```
498
634
 
499
- This will run `#show` only once, after that the rendered view comes from the cache.
500
-
501
-
502
- ### Cache Options
503
-
504
- Note that you can pass arbitrary options through to your cache store. Symbols are evaluated as instance methods, callable objects (e.g. lambdas) are evaluated in the cell instance context allowing you to call instance methods and access instance variables. All arguments passed to your state (e.g. via `render_cell`) are propagated to the block.
505
-
506
- ```ruby
507
- cache :show, :expires_in => 10.minutes
508
- ```
509
-
510
- If you need dynamic options evaluated at render-time, use a lambda.
511
-
512
- ```ruby
513
- cache :show, :tags => lambda { |*args| tags }
514
- ```
515
-
516
- If you don't like blocks, use instance methods instead.
517
-
518
- ```ruby
519
- class CartCell < Cell::Rails
520
- cache :show, :tags => :cache_tags
521
-
522
- def cache_tags(*args)
523
- # do your magic..
524
- end
525
- ```
526
-
527
- ### Conditional Caching
528
-
529
- The +:if+ option lets you define a condition. If it doesn't return a true value, caching for that state is skipped.
530
-
531
- ```ruby
532
- cache :show, :if => lambda { |*| has_changed? }
533
- ```
534
-
535
- ### Cache Keys
536
-
537
- You can expand the state's cache key by appending a versioner block to the `::cache` call. This way you can expire state caches yourself.
538
-
539
- ```ruby
540
- class CartCell < Cell::Rails
541
- cache :show do |options|
542
- order.id
543
- end
544
- ```
545
-
546
- The versioner block is executed in the cell instance context, allowing you to access all stakeholder objects you need to compute a cache key. The return value is appended to the state key: `"cells/cart/show/1"`.
547
-
548
- As everywhere in Rails, you can also return an array.
549
-
550
- ```ruby
551
- class CartCell < Cell::Rails
552
- cache :show do |options|
553
- [id, options[:items].md5]
554
- end
555
- ```
556
-
557
- Resulting in: `"cells/cart/show/1/0ecb1360644ce665a4ef"`.
558
-
559
-
560
- ### Debugging Cache
561
-
562
- When caching is turned on, you might wanna see notifications. Just like a controller, Cells gives you the following notifications.
563
-
564
- * `write_fragment.action_controller` for cache miss.
565
- * `read_fragment.action_controller` for cache hits.
566
-
567
- To activate notifications, include the `Notifications` module in your cell.
568
-
569
- ```ruby
570
- class Comment::Cell < Cell::Rails
571
- include Cell::Caching::Notifications
572
- ```
573
-
574
- ### Inheritance
575
-
576
- Cache configuration is inherited to derived cells.
577
-
578
-
579
-
580
- ### A Note On Fragment Caching
581
-
582
- Fragment caching is [not implemented in Cells per design](http://nicksda.apotomo.de/2011/02/rails-misapprehensions-caching-views-is-not-the-views-job/) - Cells tries to move caching to the class layer enforcing an object-oriented design rather than cluttering your views with caching blocks.
583
-
584
- If you need to cache a part of your view, implement that as another cell state.
585
-
586
-
587
- ### Testing Caching
588
-
589
- If you want to test it in `development`, you need to put `config.action_controller.perform_caching = true` in `development.rb` to see the effect.
590
-
591
-
592
- ## Testing
593
-
594
- Another big advantage compared to monolithic controller/helper/partial piles is the ability to test your cells isolated.
595
-
596
- ### Test::Unit
597
-
598
- So what if you wanna test the cart cell? Use the generated `test/cells/cart_cell_test.rb` test.
599
-
600
- ```ruby
601
- class CartCellTest < Cell::TestCase
602
- test "show" do
603
- invoke :show, :user => @user_fixture
604
- assert_select "#cart", "You have 3 items in your shopping cart."
605
- end
606
- ```
607
-
608
- Don't forget to put `require 'cell/test_case'` in your project's `test/test_helper.rb` file.
609
-
610
- Then, run your tests with
611
-
612
- ```shell
613
- rake test:cells
614
- ```
615
-
616
- That's easy, clean and strongly improves your component-driven software quality. How'd you do that with partials?
617
-
618
-
619
- ### RSpec
620
-
621
- If you prefer RSpec examples, use the [rspec-cells](http://github.com/apotonick/rspec-cells) gem for specing.
622
-
623
- ```ruby
624
- it "should render the posts count" do
625
- render_cell(:posts, :count).should have_selector("p", :content => "4 posts!")
626
- end
627
- ```
628
-
629
- To run your specs we got a rake task, too!
630
-
631
- ```shell
632
- rake spec:cells
633
- ```
634
635
 
635
636
 
636
637
  ### Call
@@ -743,48 +744,7 @@ end
743
744
 
744
745
  This will simply render the `author.haml` template in the same context as the `show` view, meaning you might use helpers, again.
745
746
 
746
- ### Encapsulation
747
747
 
748
- If in doubt, encapsulate nested parts of your view into a separate cell. You can use the `#cell` method in your cell to instantiate a nested cell.
749
-
750
- Designing view models to create kickass UIs for your domain layer is discussed in 50+ pages in [my upcoming book](http://nicksda.apotomo.de).
751
-
752
- ### Alternative Instantiation
753
-
754
- You don't need to pass in a model, it can also be a hash for a composition.
755
-
756
- ```ruby
757
- cell(album, song: song, composer: album.composer)
758
- ```
759
-
760
- This will create two readers in the cell for you automatically: `#song` and `#composer`.
761
-
762
-
763
- Note that we are still working on a declarative API for compositions. It will be similar to the one found in Reform, Disposable::Twin and Representable:
764
-
765
- ```ruby
766
- property :title, on: :song
767
- property :last_name, on: :composer
768
- ```
769
-
770
-
771
- ## Mountable Cells
772
-
773
- Cells 3.8 got rid of the ActionController dependency. This essentially means you can mount Cells to routes or use them like a Rack middleware. All you need to do is derive from Cell::Base.
774
-
775
- ```ruby
776
- class PostCell < Cell::Base
777
- ...
778
- end
779
- ```
780
-
781
- In your `routes.rb` file, mount the cell like a Rack app.
782
-
783
- ```ruby
784
- match "/posts" => proc { |env|
785
- [ 200, {}, [ Cell::Base.render_cell_for(:post, :show) ]]
786
- }
787
- ```
788
748
 
789
749
  ### Cells in ActionMailer
790
750
 
@@ -815,21 +775,6 @@ module MyApp
815
775
  end
816
776
  ```
817
777
 
818
- ### Base Path
819
-
820
- You can configure the cells path in case your cells don't reside in `app/cells`.
821
-
822
- ```ruby
823
- config.generators do |g|
824
- g.base_cell_path "app/widgets"
825
- end
826
- ```
827
-
828
-
829
- ## Capture Support
830
-
831
- If you need a global `#content_for` use the [cells-capture](https://github.com/apotonick/cells-capture) gem.
832
-
833
778
 
834
779
  ## Undocumented Features
835
780