[Cells-talk] content_for renders nothing
Emmanuel Gomez
emmanuel.gomez at gmail.com
Thu Dec 10 11:46:34 EST 2009
I'm currently working on a solution to a subset of this problem: exporting js requirements from a cell on a per-state basis to the parent controller. Required js will be declared per-state in the cell with a class macro (like Cell::Base.cache).
My solution has a few assumptions about the parent controller and its view, but they basically boil down to a helper module JavascriptHelper#javascript, which accepts a string and stores it in an array, and a call in the layout that invokes javascript_include_tag with the list of required files.
The final piece of the puzzle is a method Cell::Base#prepare_for(state) and a modification of Cell::ActionView#render_cell that calls #prepare_for before rendering. This allows the cell instance to call the #javascript helper method on the parent controller's template and register the required js files.
There are a lot of moving pieces; in general it's more complicated than I'd like. But, it does work with cached states. I've found content_for is problematic with caching in general. Well, any sort of side effects aside from the view complicate caching, but that's another discussion.
I have some of the described code in my fork of cells on github (http://github.com/emmanuel/cells), and most of the rest is at: http://pastie.textmate.org/737474. If anyone is interested in this, I'll add some tests for these modifications and push them to github in the next couple of days.
Emmanuel
On Dec 10, 2009, at 4:40 AM, Nick Sutterer wrote:
> hey my friend!
>
>> I like the idea of with_global_scope with nested blocks (maybe because
>> it's mine) but it seems to be tricky do make it work... or even
>> impossible. Image situation like that:
>> <% with_global_scope do |view| %>
>> <% @foo = capture do %>
>> Some text
>> <% end %>
>> <% end %>
>>
>> In that case @foo should be set in parent view. The more I think about
>> things like that the more I believe it should be simply unsupported by
>> cells.
>> In my opinion with_global_scope shouldn't be introduced into cells as it
>> may work only with content_for without a block and nothing else. Instead
>> maybe just override content_for so it may be parameterized to use cell
>> view or parent view scope.
>>
> i like your idea of #with_global_scope, too, as i would like to
> provide as much "rails" functionality in cells as possible.
> however, there are two things that prevent the introduction of
> #with_global_scope.
>
> 1. it simply breaks encapsulation. cells are meant to be independent.
> with the usage #capture and friends in cell views they access some
> globals which they shouldn't.
>
> 2. the more i dove in the rails view code, the more i got scared of
> it. the problem begins with rails distinguishing between "views" and
> "partials", and it ends with code as found in renderable.rb
>
> view.with_template self do
> view.send(:_evaluate_assigns_and_ivars)
> view.send(:_set_controller_content_type, mime_type) if
> respond_to?(:mime_type)
> view.send(method_name(local_assigns), local_assigns) do |*names|
>
> i mean, i simply don't WANT to know what's going on there!
>
>
> we should better spend our time thinking about a cell-ish approach for
> the problem of having global blocks in independent cells. many people
> want to insert JavaScript code so we could at least provide something
> for that. anyway, this should work by propagating the global block to
> the parent cell recursively where the root cell will insert the markup
> into the layout or whereever.
>
> any thougts?
> prost!
>
> nick
>
>
>
>
>> Or maybe you've got an idea of wider use with_global_scope, I mean not
>> limited to content_for only?
>>
>> zdrówko
>> --
>> Michał Łomnicki
>>
>>
> _______________________________________________
> Cells-talk mailing list
> Cells-talk at rubyforge.org
> http://rubyforge.org/mailman/listinfo/cells-talk
More information about the Cells-talk
mailing list