Cells Got content_for Support.

After decades of struggling with myself, and after a fantastic “RubyConf Australia”:http://www.rubyconf.org.au/ with lots of love I finally managed to give cells users support for a global (brrr) @#content_for@ helper.

h3. Using It.

The new helper is added by including the “cells-capture”:https://github.com/apotonick/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

You can now use the helper in your views – it will append passed content to the global buffer.

  - content_for :javascripts

h3. 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.

h3. 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)

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.

  def js
    render # this could be a JS template

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.


One thought on “Cells Got content_for Support.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s