coletrain
coletrain

Reputation: 2849

Rails render partial without entire html layout

Ok so I have a problem with rails and rendering partials. I have a layout called profile and inside of the profile layout I have all my js, stylesheets, etc included.

<html>
<head>
  <title>Profile</title>
    <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" %>
    <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js" %>
    <%= javascript_include_tag "application" %>
    <%= stylesheet_link_tag "main" %>
    <%= stylesheet_link_tag "reset" %>
    <%= csrf_meta_tag %>
</head>

<body>
 <%= yield %>
</body>
</html>

Inside of the yield tag(profile/index.html.erb) above is the following

<%= render :partial => 'pages/page', :layout => "layouts/default", :locals => {:page => @page } %>

Now in the pages/page view there are the same default tags such as css and js files. When i remove the css styles then I lose the styling for the pages/page view. Is there a way I can render a partial without recalling the same css and js files or what is a better way to go about doing something like so?

Upvotes: 4

Views: 10065

Answers (4)

Mark Fraser
Mark Fraser

Reputation: 3198

You need to pick one or the other: layout the original method call, or pass a layout to the partials. Doing both would be illogical.

There is a more thorough discussion here:

http://www.mikemayo.org/2012/rendering-a-collection-of-partials-with-content_for

Upvotes: 3

Richard Peck
Richard Peck

Reputation: 76784

A partial is basically just a "slice of page" (like slice of cake... but in code form). It's designed to populate a small part of the page; typically one which will by dynamically updated depending on page variables.


Seems like you're confusing the purpose of layouts, views & partials in my opinion. If you want to dynamically load CSS / JS, put a "content_for" block in the profile views with a default layout, like this:

Layout

#layouts/default.rb
<html>
<head>
  <title>Site Title</title>
    <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" %>
    <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js" %>
    <%= javascript_include_tag "application" %>
    <%= stylesheet_link_tag "main" %>
    <%= stylesheet_link_tag "reset" %>

    <%= yield :header_includes %>

    <%= csrf_meta_tag %>
</head>

<body>
 <%= yield %>
</body>
</html>

Views

#views/profiles/index.html.erb
<% content_for :header_includes do %>
    <%= stylesheet "profile_custom_css" %>
<% end %>

Partial

Partials could be used to keep your code DRY & give the output of specific header files, like this:

Partial

#views/elements/_custom_header.rb
<% content_for :header_includes do %>
   <% headers.each do |type, value| %>
       <% if type == "java" %>
           <%= javascript_include_tag value %>
       <% else %>
           <%= stylesheet_link_tag value %>
       <% end %>
   <% end %>
<% end %>

View

#views/profiles/index.html.erb
<%= render :partial => 'elements/custom_header', locals: { :headers => [["java", "profile_custom"], ["stylsheeet", "profile_custom"]] } %>
#Resume standard view code here

Layout

#layouts/default.rb
<html>
<head>
  <title>Site Title</title>
    <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" %>
    <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js" %>
    <%= javascript_include_tag "application" %>
    <%= stylesheet_link_tag "main" %>
    <%= stylesheet_link_tag "reset" %>

    <%= yield :header_includes %>

    <%= csrf_meta_tag %>
</head>

<body>
 <%= yield %>
</body>
</html>

I've not tested passing the partial locals as a hash, so the syntax may be incorrect, but this is what we'd do to load up the required code. The added benefit is that content_for only yields content that has been defined (I.E you just have to include yield :custom_headers and it will only show if the content block is present)

Upvotes: 1

Joel Jackson
Joel Jackson

Reputation: 1080

I always create the option to overwrite the stylesheets as follows:

<%= stylesheet_link_tag content_for?(:stylesheets) ? yield(:stylesheets) : "application", :debug => Rails.env.development? %>

Then inside a view

<% content_for :stylesheets %> some stuff or nothing in here <% end %>

That will let you specify in a view rendered in a layout you want no stylesheets and the same principle applies for javascripts.

That having been said if you are rendering a partial inside a layout that has an html tag and head etc. you should probably investigate if there is a better way to do what you are doing.

Upvotes: 4

Siwei
Siwei

Reputation: 21617

I rarely see the usage of( or I am wondering if Rails support this usage... )

<!-- confirmed, this usage will cause error in Rails 3.2  -->
<%= render :partial => "some_partial", :layout => "some_layout" ... %>

I prefer to choose the specific layout in the controller:

def some_action
  # some code
  render :layout => "some_layout" 
end

Upvotes: 3

Related Questions