Template in a Template

Greetings!

Okay, here is my situation: I have a template with a 3-column layout. The first column is printed out in the template, and the following two columns are generated by the controllers. It is often the case that the controllers only fill up the middle column, and the last one remains empty, though sometimes the last one is used.

Template:

Do you have an application layout defined?

I use the app layout to set the major parts (banner, left column, a yield area, and the footer).

(app layout, abbreviated, also using haml, not erb notation)

%body   #site-whole     #site-banner= "My App"     #site-columns       #site-left         = render_partial 'layouts/nav_ref_links'         - if current_user.is_admin?           = render_partial 'layouts/admin_links'       #site-spacer       = yield     #site-spacer2     #site-footer       = render_partial 'layouts/footer_user'

In the middle of that template is the yield for the current page's content (which is the middle "column" of data), and the current page determines whether it uses the third column or not (which it invokes as a partial). So the pages that do show that third column just include a "= render_partial 'layouts/relateds'" call, others don't. Not much clutter there, and for the parts that don't change often, fragment caching works great.

If I understand you correctly, you have a three column layout that either: - fills in only two columns - fill in three columns

And the decision about how many to fill in is based on the action (page, as you say).

If that's the case then you can use the 'layout' command on a controller by controller basis, with the :except and :only options to do the switching that you need. You could have a layout called 'layout_with_empty_column' and 'standard' and the layout command in your controller would choose appropriately.

If that's not fine grained enough control (ie., you need to switch based on data rather than simply the action) then I think you can include :layout in your call to render. You would need to call render explicitly (not just the default action/view name matching) to make this work.

Thank you for your two suggestions.

I would prefer to avoid having two full templates. This would seem to complicate the situation. I am trying to reduce the amount of code that has to change if the template design were to change. I am trying to minimize the amount of data spit out by each view so that I don't have to go through the tedious work of modifying every view.

It would be nice if I could catch the output of a particular action's view _before_ it sends it to @content_for_layout in my layout file. I could then take the output of that action, throw it inside my div skeleton at the right spot, and then it could be passed onto the layout file as @content_for_layout.

I suppose one way to approach this is to add more logic in the template file that alters where @content_for_layout goes depending on a class variable set per action...

-Matt