views:

74

answers:

1

First off, let me say that I am familiar with content_for. It's not really what I'm looking for here.

I want to allow a template and any number of partials to build up, say, a list of JavaScript files I want to load, and pass them up to the layout for it to process and add to the <head> area. I only want to load the files if the page actually needs them, so I'd rather not just put them all into the layout. Nor does it seem like something to be handled by the controller, because these are mainly view-specific changes.

I've tried using content_for to return an array of names, but that doesn't seem to work. It also wouldn't allow for multiple partials to add their own prerequisites to the list. I've also tried using helper functions in the template/partials to add to a list, and then using that list in the layout, but it appears that the layout code is evaluated before the template code.

Any ideas? This isn't JavaScript-specific, by the way; I simply need a way to pass Ruby objects from the template/partials to the layout.

EDIT: Per request, an example. css_import is just a helper I wrote that emulates a CSS @import.

# In the layout
<style type="text/css">
<%- yield(:foobar).each do |foo| -%>
  <%= css_import foo %>
<%- end -%>
</style>

# In the template
<%- content_for :foobar do
  ['layout', 'recipes', 'user']
end -%>

# The actual output from View -> Source
<style type="text/css"> 
</style>
+1  A: 

Maybe you should have a look at what content_for is doing? It just executes the block you assigned to the call and stores it in an instance variable. When calling yield with the right parameter it return the instance variable.

It should be perfectly possible to create two helper methods of your own to accomplish your goal, for example:

def register(key, value)
    @registry[key] = value
end

def fetch(key)
    @registry[key]
end

You can make these functions as fancy as you like, for example when the registry contains only locations to JavaScript files, you can return HTML JavaScript include tags instead of just the file path.

Edwin V.
Crazy; I swear I tried something just like that before and it didn't work. Now my only problem is that if I call a partial from the layout, and I register() something in that partial, it doesn't apply (because it's already past the part where I used fetch().
Twisol
Dig deeper into the Rails source code, they should have solved this problem :-)
Edwin V.
I didn't think I'd have to look at the Rails *source* when this is just my first project. \*laughs\*
Twisol