views:

1399

answers:

4

Sorry for the slightly noobish question, as I am writing my first rails app. I get the idea of the layout view, but if you are using them, is there any way to include a view specific js or css file? For example, I have layouts/products.html.erb, and for products/edit.html.erb I want products_edit.css, but I don't want that css for all product views, what is the best practice to accomplish that?

A: 

Try this in layout file:
<% if controller.action_name == 'index' %>
<%= stylesheet_link_tag 'index' %>
<% else %>
<%= stylesheet_link_tag 'else' %>
<% end %>

Bozydar Sobczak
That would get you the 'else' stylesheet for every action named index on every controller that uses that default layout. You almost certainly want an alternate layout file in this case.
Otto
A: 

You can't if your </head> tag is in your layout.

You may want a different layout for that controller action. Like this on the render:

 render :action => "index", :layout => "some_other_layout

Also you can set a different default layout for a whole controller with this line in the controller class:

layout "some_other_layout"

Check the API docs, there's some complex things you can do with conditionals on that layout method.

Otto
-1, you are wrong. Using yield(:header) and content_for :header you can specify additional content for the head tag.
Samuel
That doesn't change the fact that the rest of it is perfect legitimate solution to the problem.
Otto
No, but it violates the DRY principle that rails loves so much.
Samuel
How so? I can resolve duplication in the layouts via partials, if there's enough of it.I'd say your solution pushes too much knowledge of the layout down into the templates that ought to be ignorant of what they're contained in, aside from a clearly delineated contract.
Otto
Using a different layout just to add one css file will introduce duplicated code in the layout. When you can add functionality that is very powerful and very DRY. And you really shouldn't be so petty about the down vote, don't take it personally.
Samuel
Again, if there's a lot of duplication between layouts, I can use partials to resolve it.And I didn't down vote you.
Otto
+4  A: 

If you have a generic edit.css file, I would suggest an if in your layout

<%= stylesheet_link_tag 'edit' if params[:action] == 'edit' %>

Otherwise you can use content_for with a yield to add additional tags into the head.

layout.html.erb

<head>
  ...
  <%= yield(:header) if @content_for_header %>
</head>

products/edit.html.erb

<% content_for :header do -%>
  <%= stylesheet_link_tag 'edit_product' %>
<% end -%>
Samuel
exactly what I was looking for, thanks :)
Matt Briggs
I'm not sure you want '<%=' on the stylesheet_link_tag line. You don't want to output that on the edit view.
erik
Yes you need it, the views use a helper called capture which takes a block, this helper will redirect all output to a variable which is then rendered in a different location. So my solution gives you more flexibility and feels more natural.
Samuel
+1  A: 

You can add a stylesheet tag inside the head tag of the layout by doing something like this:

layouts/products.html.erb:

<head>
  ...
  <%= yield :css %>
  ...
</head>

products/edit.html.erb

  <% content_for 'css' do
    stylesheet_link_tag 'products_edit'
  end %>
erik
+1, but Samuels answer was slightly better put together
Matt Briggs