After decades of struggling with myself, and after a fantastic RubyConf Australia with lots of love I finally managed to give cells users support for a global (brrr) #content_for helper.
Using It.
The new helper is added by including the cells-capture gem into your Gemfile.
gem 'cells-capture'Cells need to declare explicitly that they want #content_for to access the global buffer by including Cell::Rails::Capture. This is meant to remind users that they’re kinda breaking their encapsulation (although it feels handy, I admit).
class BassistCell < Cell::Rails include Cell::Rails::Capture def show render end end
You can now use the helper in your views – it will append passed content to the global buffer.
%div
- content_for :javascripts
$('#pick').append("Yo!")Now What Is Your Problem?
We want cells users to have maximum comfortability, that is why the new helper is here. However, there are two problems with this approach.
- You’re changing state of a global variable from a well-encapsulated cell.
- A cached cell will mess up the global as you expect the cell to append something but it actually doesn’t (remember, there’s a cache hit).
Especially the latter is a problem: Imagine you’re rendering a page with a cached cell: the JavaScript of this component will be lost as the #content_for block is never called! This is a well-known problem in traditional Rails views where people call #content_for in a #cache block.
A Way Out?
A more explicit way of collection JavaScript from view components could help.
render_cell(:bassist, :play) do |cell| content_for(:global_js, cell.js) end
Here, instead of calling #content_for in the cell’s view, you dedicate an additional method to it responsible for rendering the JavaScript (or any other content).
class BassistCell < Cell::Rails cache :play def play render # usually, content_for happens here. end def js render # this could be a JS template end end
The content of the #js view will be added to the :global_js buffer. The cool thing: It will be invoked even when #play is cached!
Anyway, let us know how you use it and enjoy.


Mattias
Nick, thanks for following up on this issue, didn’t even think about calling content_for in the cell block.