Those of you having asked for mountable cells will be happy with the recent 3.8.0 release! We entirely removed the ActionController dependency. That essentially means you can have cells outside of the standard Rails stack. Cool, heh?

Cells 3.8.0 Released

Two little things in 3.8 changed. Cell::Base and Cell::Rails are now different classes with different semantics. Don’t panic – if you still derive your cells from Cell::Rails and use the #render_cell interface, only, nothing will change for you.

However, we had to tweak the API of some semi-public methods, here’s the new signatures.

Cell::Rails.create_cell_for(name, controller)
Cell::Rails.render_cell_for(name, state, controller, *args)

Well, nothing serious, it’s just the controller sliding to the end. If you use this anywhere, be sure to change it.

What’s new?

What is new is that Cell::Base is now decoupled from the ActionController. There simply is no AC-reference in Base anymore. However, this reference is still managed in Cell::Rails on purpose:

  • Calls to #url_for and friends automatically query the parent controller for host and action name. This makes it easy to embedd cells into a controller view and still having correct links in the cell.
  • Having the AC reference, people can still use request, params and session – if they need it. We strongly discourage accessing HTTP properties from a view component, though.

Let’s see what the new decoupled Base brings us.

Cells on Routes.

Deriving your cell from Base makes it routeable.

class PostsCell < Cell::Base
  def show
    @posts = Post.find(:all)
    render
  end

Routeable? Mountable? Well, let’s look at config/routes.rb to understand this.

match "/posts" => proc { |env|
  content = 
    Cell::Base.render_cell_for(:posts, :show)
  [ 200, {}, [ content ]]
}

How cool is that? You can mount a cell to a route without the ActionController overhead and still use the rendering, the caching and testing you all love from Cells. And, hey, it’s super super fast now.

The lack of the AC dependency makes cells even more versatile.

More on Routing

Since we got rid of the AC instance we have to take care of our URLs ourself. The cell still has access to all the URL helpers. Nevertheless, those helpers usually query the controller for host name portions, etc. That’s actually very simple with cells, too.

class PostsCell < Cell::Base
  def default_url_options
    {:host => "apotomo.de"}
  end

Just override the #default_url_options method as used from AC. This allows using the URL helpers as usual.

PostsCell.new.posts_url
#=> "http://apotomo.de/posts"

Let me know how these changes work for you! I’m eager to see new cases of applications in the next weeks.

Tags: ,

8 Responses to “Mounting a Cell to a Route with Cells 3.8.”

  1. Hi,

    since I’m pretty new to cells and reading your rack example I was wondering if it would make sense to get a rack compatible object from cells directly.

    thus your example above could be something link:

    match “/posts” => Cell::Rack.new(:posts, :show)


  2. sasuke

    is there the same possibility also for apotomo?


  3. TauPan

    I’ve been one of the people waiting for routable cells, so it’s kind of a christmas present, thanks! ;)


  4. Kevin Triplett

    Sie regieren!!

    Thanks, Nick — I can see where this is heading with Apotomo.

    So if we wanted to create an app that used ONLY cells and no AC whatsoever, then we need a cell that creates the layout? Is that right? So instead of AC automatically choosing the layout template, we write a cell that creates the HTML header, body, etc and then plugs in the cells that render the specific body (or header/whatever) content?


  5. nick

    @bumi: Love the Cell::Rack idea!

    @Kevin: Yeah, you could either go and have two cells, or use the :layout option in render.

    @sasuke: For Apotomo, I need a couple of more hours to think about it, I will blog when it’s ready.


  6. Paul
  7. Looking forward to the possibilities!


  8. Rami

    Why not using the cell higher in the middleware? using it on routing is already after the whole rackstack is loaded (as I understand) so its not performant enough.

Leave a Reply