Topic: The application.rhtml

Sorry for the title but I couldn't come up with a better one.

Here is my problem:
This is the _basic_ design of my application.rhtml


                     top           
-----------------------------------------
|sidecontent  |  maincontent  |

Until now I used content_for, but I've been told that you can't use caching with content_for.
Is that so and if yes is there any alternative to copy & paste big parts of the html design into every view?
Long story short, what ist the best solution for such a design?

Thank you.

Last edited by carnz (2007-04-02 10:54:10)

Re: The application.rhtml

Hi Carnz,

I don't know exactly what you mean by using content_for but the normal way of doing this is to move the common stuff you want in your views into the application controller, something like this:

<html>
<head>
  <title>My site!</title>
</head>
<body>
  <div id="header">
    Welcome to my site!
  </div>
  <div id="menu">
    menuitems
  </div>
  <div id="content">
    <%= yield %>
  </div>
</body>
</html>

Now the place you put the "yield" method is where your content will be displayed. Is this what you meant?

Re: The application.rhtml

Not exactly.

My application.rhtml looks something like this:

<html>
<head>
<title>My site!</title>
</head>
<body>
   <div id="header">
    <%= yield :header%>
  </div>
  <div id="menu">
     <%= yield :menu%>
   </div>
   <div id="content">
    <%= yield :maincontent%>
   </div>
</body>
</html>

And the viewer:
<% content_for :maincontent do %>
  <div> some html.. </div>
<% end %>
<% content_for :header do %>
  <div> header.. </div>
<% end %>

and so on...
Now someone told me, that you can't or it might be very difficult to use caching when using "content_for". Is that true? Is the "content_for" solution for my layout a good solution?

Last edited by carnz (2007-04-02 14:16:46)

Re: The application.rhtml

Ah I see what you mean.. I'm sorry I haven't used content_for very extensively so I'm not sure whether or not caching works well with it.

Re: The application.rhtml

It helps to understand what is happening behind the scenes. When you use "content_for :header" it is creating an instance variable called "@content_for_header" which holds the result of the block. When you do "yield :header" in the layout this just outputs @content_for_header.

Whether or not caching works depends on the type of caching you are using. Page caching should work. Action caching I'm not sure about. Fragment caching won't work because it's not smart enough to cache the content into the instance variable.

Are you certain you need to use content_for? Do you need the content to change depending on every template that is rendered? perhaps a partial is a better solution.

Railscasts - Free Ruby on Rails Screencasts

Re: The application.rhtml

Well, not depending on every Template but still very often. I could code some workaround with a partial but I think this is not one of the best solutions.

Re: The application.rhtml

OK just tried caching with content_for

<% content_for :menu do %>
  <% cache("menu") do %>
   <%= Time.now %>   
  <% end %> 
<% end %>

and it worked...

Re: The application.rhtml

Oy, you're right. I was thinking of caching around the yield which won't work:

# in layout
<% cache("menu") do %>
  <%= yield :menu %>
<% end %>

Because if the menu changes in the template then the cache won't know about it and will still spit out the cached version.

Railscasts - Free Ruby on Rails Screencasts