Reputation: 1349
I have a Rails app, in which I fit my entire website into a 980width container with the following code in my 'application.html.erb' file:
<div class="container_980 white shadow-horizontal">
<div class="container">
<%= render 'layouts/flashes' %>
<%= yield %>
</div>
</div>
Now, I want to make 2 file exceptions for fitting the content within the container. I want the index page and another page to expand across the entire page, so I need to get those two pages outside of the common 'yield' set above.
I tried doing so with:
<% if current_page?(root_url) %>
<%= yield :index %>
<% elsif current_page?(:controller => "tracks", :action => "show", :id => params[:id])) %>
<%= yield :show_track %>
<% else %>
<div class="container_980 white shadow-horizontal">
<div class="container">
<%= render 'layouts/flashes' %>
<%= yield %>
</div>
</div>
and
<% content_for :show_track do %>
blah blah blah
<% do %>
THE PROBLEM: The show_track page doesn't load. I did some searching, and it seems like the above method should work, but it's not, and I was wondering if I needed to do something else as the "show" page was made through scaffoldaing(RESTful).
Is there a better way to take out the 2 pages from the container than using if..else conditions?
Upvotes: 0
Views: 682
Reputation: 34072
Is there a better way to take out the 2 pages from the container than using if..else conditions?
This is subjective, but I would use nested layouts, then define the layouts for each page type in the controller.
First your basic top level layout. I'm calling it "application", the default, but you could call it whatever. Note how if there's content_for? :application
it will yield it, otherwise it will just yield. This is key to the setup. All nested layouts should follow a similar pattern; in this way they can render further nested child layouts, or be used as layouts themselves.
<!-- layouts/application.html.erb -->
<html>
<body>
<%= content_for?(:application) ? yield(:application) : yield %>
</body>
</html>
Then for the container, you'd define layout which can be nested inside "application", this one setting up your container HTML and rendering content inside.
<!-- layouts/container.html.erb -->
<%= content_for :application do %>
<div class="container_980 white shadow-horizontal">
<div class="container">
<%= render 'layouts/flashes' %>
<%= content_for?(:container) ? yield(:container) : yield %>
</div>
</div>
<% end %>
<%= render :file => "layouts/application" %>
Then just move your conditional logic to the controller, like:
layout :determine_layout
protected
function determine_layout
# pseudocode here, you get it
(index or tracks) ? "application" : "container"
end
You could stop there. Continue to see how you might further nest layouts.
However you could go further, and use the nested layout setup to nest arbitrary numbers of different layouts. Say, for example, that tracks had another content block you needed to fill. You could define another nested layout, like:
<!-- layouts/tracks.html.erb -->
<%= content_for :some_other_block do %>
// stuff that should be in some other block
<% end %>
<%= content_for :container do %>
// stuff that should be in the container
<% end %>
<%= render :file => "layouts/container" %>
Then in your controller, you'd change your determine_layout
to set the "tracks" layout for tracks, e.g.:
function determine_layout
# pseudocode here, you get it
if index
"application"
elsif tracks
"tracks"
else
"container"
end
end
Upvotes: 2