Rendering multiple erb in rails - ruby-on-rails

I have layour/application.html.erb with all required headers and nav bar. I have yield only in body section.
My dashboard.html.erb is hope page which is set of graphs. I want to write each graph in a different erb and its own javascript. So I sketched up,
dashboard.html.erb as:
<div> hello </div>
<%= render 'hierarchical' %>
and
dashboard/_hierarchical.html.erb as:
<head>
<%= javascript_include_tag "_hierarchical.js" %>
</head>
<div id="chart">
test something
</div>
I think I need to read more about ruby which I will but need quick help on this so that I can have my sample demo app running asap. Thanks for your help!

I was doing it wrong without using :partial symbol.
This code worked
<div> hello </div>
<%= render :partial => 'hierarchical' %>

Related

DRY view for sidebar

In my quest to keep my application views as DRY as possible I've encountered a little snag. My appliation.html.erb incorporates a static sidebar menu. Each of my main controllers incorporates a secondary sidebar menu (essentially a submenu). I can take the code that renders the menu out of application.html.erb and put it in each of my views and change the secondary sidebar there, but this produces a lot repetition in my views.
I saw this SO post and looked at this page, but I was unable to get either idea to work. I was thinking that I could put something like:
<% provide(:submenu, 'layouts/sidebars/sidebar_customers_contacts') %>
at the top of each view and use that to render the associated partial by doing
<% content_for(:submenu) do %>
<%= render :partial => :submenu %>
<% end %>
from the application.html.erb but of course that didn't work.
This is my current application.html.erb:
<div class="side">
<%= render 'layouts/sidebar' %>
<%= render 'layouts/sidebars/sidebar_dashboard' %><!-- this needs to load a sidebar based on the controller that calls it. Each view of the controller will get the same sidebar. -->
</div>
<div class="main-content">
<%= yield %>
</div>
I feel like I'm making this more difficult than it really is. Is there a simple way to do this?
Rails provides a helper called controller_name which you can read more about here.
Assuming you adhere to your own naming conventions, this should work as-is. If you decide some controllers don't get a sidebar, you may need to throw in some conditionals...
application.html.erb
<div class="side">
<%= render "layouts/sidebar" %>
<%= render "layouts/sidebars/#{ controller_name }" %>
</div>
<div class="main-content">
<%= yield %>
</div>
EDIT
Sorry, my mistake was using single quotes instead of double-quotes. You cannot use #{string interpolation} within single quotes. Source

Rails what does this "yield" do?

What does the yield do in this snippet?
<body data-spy="scroll" data-target=".sidebar">
<!-- Your timezone is <%= Time.zone %> -->
<!-- <%= "Ruby Version is #{RUBY_VERSION}" if Rails.env =~ /test|development/ %> -->
<%= render partial:'shared/account_status' %>
<%= render partial:"shared/session_timeout" %>
<div class="container">
<%= render partial:"shared/branding" %>
<%= render partial:"shared/nav", locals:{icons:icons, actionable_urls:actionable_urls, top_level_items:MenuItem.top_level_items_with_access_rights_for_user(current_user).sort{|a, b| a.sequence <=> b.sequence}, current_item:current_navigation_item} %>
<div style="clear:both"></div>
<div id="content">
<%= render partial:"shared/flash", object:flash %>
<%= yield %>
</div>
</div>
<%= render partial:"shared/ldap_user_menu" if signed_in_as_ldap_user? %>
</body>
SOLUTION
see #Christian_Rolle 's answer below
The reserved Ruby key word yield is for processing closures (like a Proc or lamda). That said it is some kind of placeholder for processing some logic.
In Ruby on Rails view templating it is used for merging in partials. In the case of a layout file like the application.html.erb it merges in controller response templates like index.html.erb or show.html.erb.
Think of it as a placeholder for your controller response HTML in a global layout environment.
Read more at: Understanding yield
or about Ruby closures:
Do the Proc! ... a Ruby closure and
Have a lambda! ... a Ruby closure
okay ... lets talk about it in easy way , yield is like a placeholder or like a container . And while you make different parts of view and want to show it on any specific layout file , then you can just call that part on the yield section . And this is all it does .

Yield layout in rails

I'm trying to add a layout to the application layout. I having trouble trying to figure out all the different layout solutions. First I tried just a layout inside a layout because I didn't fully grasp what partials are or if they are layouts also? Maybe I can start with that question. What is the difference between a layout and a partial.
Here is what I have right now. I'm trying to just separate out my header code which has a navigation and some other elements into a separate layout. I want this layout to be on all views. Meaning it should be a layout inside the applications layout along with other views that are been called when their controllers are called. Which is covered in my code with the <%= yield %>. That yeild works but the :header one does not.
Application Layout app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>home</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="header"><%= yield(:header) %></div>
<%= yield %>
</body>
</html>
Header layout app/views/layouts/application.html.erb
<% content_for :header %>
<p>HEADER TEXT</p>
<% end %>
Why would the code above not work?
I also saw code like this that I tried but it gave me an error.
<%= render layouts/header %>
Can someone please explain all these different methods.
Thanks.
It's good practice to separate your header and footer into partials which you would live in the views/layouts folder as '_header.html.erb' and '_footer.html.erb' respectively.
You can then optionally wrap each partial with specific div's which is what you're trying to do with the header (you could do the same with the body too), and it would end up looking like this:
<!DOCTYPE html>
<html>
<head>
<title>home</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="header">
<%= render 'layouts/header' %>
</div>
<%= yield %>
<div id="footer">
<%= render 'layouts/footer' %>
</div>
</body>
</html>
That will do what you want it to do.
Note that 'layouts/header' and 'layouts/footer' have '' around them.
To answer your question on what is the difference between a layout and a partial, well a layout is something that will used throughout your application, such as a consistent header or footer. A partial can be a layout, but it doesn't have to be, so you can partial specific to other views across your site.
<% content_for :header do %>
<p>HEADER TEXT</p>
<% end %>
You forgot the do
So - first - The yield syntax may or may not be correct, but I've never seen it, and I don't like it. I only ever call yield once in a file.
If you want to render a header in your application template file, that's certainly possible - my advice would be to place it in your template file directly - after all, that's what template files are for. If you want to completely encapsulate your header for some reason or another in seperate files, what you need is partials. You're going to do something like this:
<body>
<%= render :partial => "shared/header" %>
<%= yield %>
</body>
Which will render your header content, stored in /shared/_header.html.erb into the layout here.
Check out this guide here for more info

how to extend child template to parent in rails

I am new to rails. I am having difficulty in understanding template inheritance. Earlier I have worked in django and seen template inheritence there. There I saw child is told about parent using "extends" command. Can anyone explain how it works here. I have gone through guidelines of ruby but it was not clear.
Thanks
It's quite simple to do in Rails.
You simply tell the template you are currently rendering to render another template.
For example layouts/application.html.erb contains something like this:
<% content_for :navigation do %>
<nav>...</nav>
<% end %>
<% content_for :content do %>
<%= yield %>
<% end %>
<%= render :template => 'layouts/main_application' %>
The important part is the render :template part that then delegates this template to also render the layouts/main_application.html.erb that in my case looks something like this:
<header>
...
</header>
<body>
<%= yield :nav %>
<%= content_for?(:content) ? yield(:content) : yield %>
</body>
What I am doing here is having a main template that does not contain the navigation (for things like login etc) and the application.html.erb adds that navigation to the :nav content placeholder.

Nested layouts in ruby on rails

I'm new to rails and am trying to work out how to get nested layouts working; I'm assuming they're a bit like .net master pages?
I've followed this guide and I've created an application.erb.html in my layout directory which contains this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title><%= #page_title or 'Page Title' %></title>
<%= stylesheet_link_tag 'layout' %>
<style type="text/css"><%= yield :stylesheets %></style>
</head>
<body>
<%= yield(:content) or yield %>
</body>
</html>
and have modified one of my existing layouts to this:
<% content_for :stylesheets do %>
<% end -%>
<% content_for :content do %>
<p style="color: green"><%= flash[:notice] %></p>
<%= yield %>
<% end -%>
<% render :file => 'layouts/application' %>
When I go to one of my views in the browser, absolutely nothing is rendered; when I view source there is no html.
I'm sure there's something elementary I've missed out, can anyone point it out please?!
I've worked out the solution, although it's not what's given in this article
I've replaced this line
<% render :file => 'layouts/application' %>
with
<%= render :file => 'layouts/application' %>
I'm not sure if the article is wrong, or I've found the wrong way to fix it! Please let me know!
Cheers
The original article had an error, and your solution is correct. Here's the reason:
The output of ruby code in an ERB (view) that is encased in <%= %> gets added to the HTML that's generated and sent to the browser. The output of ruby code that is encase in <% %> does not get added to the HTML. So calling <% render :partial ... %> has no effect since the result of that ruby code (fetching the partial) isn't added to the generated HTML file.
<% %> is generally reserved for conditionals and loops, as you have in the example above.
Here is a different approach to nested layouts that may come out handy.

Resources