is it possible load a file.js.erb in <head></head> - ruby-on-rails

I have a file.js.erb file in my views, but I need load this file in <head></head> layout.
Is it possible load these files in <head></head> section?
and if it's possible, How can I do it?
Thanks!

in your layout:
<head>
<script><%=render :file => "layouts/file.js"%></script>
</head>
If the file contains script tags then you wouldn't need them in the layout, and change the layouts in the path to wherever the file actually is.
If you don't want it on every page then you can use content_for and yield (as MyYorshiji suggests in the comments)
<head>
<script><%= yield :extra_js %> </script>
</head>
In the view html.erb where you want this js to load
<%content_for :extra_js do %>
<%=render :file => "layouts/file.js"%>
<% end %>
http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-content_for

Related

How to call a .html.erb file inside another .html.erb file

I have a structure which looks like below where-in I need to call a .html.erb file in another.
main_layout.html.erb
<html>
<head>
</head>
<body>
<div>
how to call the sub_layout here
</div>
</body>
</html>
sub_layout.html.erb
<div>
<p> This is the nested layout to be rendered inside main_layout </p>
</div>
I tried with the below options.
<%= render sub_layout.html.erb %>
<%= ERB.new(open("sub_layout.html.erb").read).result(binding) %>
Both of the above options is not working. Any suggestions please?
# main_layout.html.erb
<html>
<head>
</head>
<body>
<div>
<%= render 'sub_layout' %>
</div>
</body>
</html>
This will look for a file _sub_layout.html.erb in the same folder as main_layout.html.erb
If the _sub_layout.html.erb is not in the same folder as main_layouts.html.erb you need to define the complete path <%= render 'your/path/to/sub_layout' %>
I think you can rename your file from "sub_layout.html.erb" to "_sub_layout.html.erb" and run it.

What does “yield” do?

What does yield do in ruby on rails?
<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>
It tells Rails to put your view content to this block (which is called by yield) at that place in the layout file.
Checkout the rails guide to learn more about the ActionView.
https://guides.rubyonrails.org/action_view_overview.html
As pointed out by #Aleksei Matiushkin, yield is pure ruby, so you should also learn more about that in your own time.
Here's a (my) visual presentation to explain what happened on that line:
view.html.erb:
<p>Hello there!</p>
<p>I'm a content from view</p>
layout.html.erb:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
Now the results will be like this:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Hello there!</p>
<p>I'm a content from view</p>
</body>
</html>
Your question is not specific enough. In Rails, as with ordinary Ruby, yield used within a method definition represents the block that is passed to a method.
However, judging from the code block that you gave, you seem to particularly want to ask about yield used in layouts of a view in Rails. In such case, it represents the main content described in the view file that is to be rendered in the context. For example, when the controller is Foo, and the action is bar, then, yield used within a layout to be used in such context will be replaced by the content of /app/views/foo/bar.html (or whatever corresponding view file in other format).
It must be simple in your concept: yield is where put content block (html) from action view to layout template
example: action index render index.html, the result will be put/filled in the yield
I haven't seen render mentioned in the other answers, so I'd like to add to #vipibano's answer, that if you want to understand how this yield business works in Rails (and more specifically in the application.html.erb), you'll benefit from:
understanding how blocks work in Ruby (as mentioned by others)
understanding what Rails' render method does
The render method is called at the end of a controller action and orchestrates what block is passed to the method that is actually rendering the application.html.erb.
I've tried to visualize this a bit and there a few examples if you want to dig deeper in the according post:
https://richstone.io/debunk/

How to conditionally add class to <body> in rails layout

My application.html.erb file looks like this
<!DOCTYPE html>
<html lang="en">
<head>
.
.
.
</head>
<body <%= "class=landing-bg" if !#landing.nil? %>>
<%= render 'layouts/header' %>
<div class="container">
.
.
.
</div>
<%= render 'layouts/footer' %>
<% if !#landing.nil? %>
<div class="landing-gradient"></div>
<% end %>
</body>
</html>
I've left out a bunch of meta tags in the <head> and a bunch of other code in the body that's unrelated to the question.
static_pages_controller
def home
#landing = "landing"
end
I need to add a class to <body> and a div below the footer only on my home page. I feel like what I am doing is a bit hacky. And, if I created a separate layout just for the landing page it wouldn't be DRY since I would be repeating alot of code that's on this layout.
What is the best way to do this? What is the rails way?
My typical pattern is to add the controller and action into the class of the body, and then use those as selectors in my css like this:
<body class="<%= controller_name %> <%= action_name %>">
<!-- etc -->
</body>
As for your second issue of a conditionally body on only the home page, you can simply add that into the body in the main layout and display it only on the landing page:
<body class="<%= controller_name %> <%= action_name %>">
<!-- etc -->
<div class="landing-gradient"></div>
</body>
# application.css
.landing-gradient {
display: none; // Hide the gradient
}
.landing .landing-gradient {
display: inline; // Show gradient b/c of more specific selector
}
This is my personal preference since you're leaving display of individual elements to the css / presentation layer instead of within your controllers.
Finally, you could also use a content_for around the footer so that you can customize the footer across individual pages. That's a bit heavy handed for your example though, so I'd only use that if you were customizing the footer a lot.
In my case I want to have a different class per layout (at least potentially), so in app/views/layouts/application.html.erb I do this:
<body class="<%= yield(:body_class) %>">
and then in my layout file I do this:
<% content_for(:body_class) { 'my-class' } %>
You can also manage it without creating an instance variable and verifying it in your view but using the params[:action] and params[:controller]:
<body class="<% 'class_value' if params[:controller] == 'static_pages' && params[:action] == 'home' %>"
You can just validate for the action (method) if you don't have more than one home method.

Passing objects to be used by partials inside a layout

I have a page layout with a sidebar and a main content. Both are dynamic according to the user profile.
<html>
<body>
<%- partial('partials/sidebar')%>
<html with <% ejs code %> for body>
</body>
</html>
Sails view should be:
res.view( {mydata} );
How can I pass data to the partials so it can be dynamically rendered instead of static?
Example:
controller:
res.view( {mainContent:{mainContentJson}, sidebar:{sidebarJson} );
layout.ejs:
<html>
<body>
<%- partial('partials/sidebar', sidebar)%>
<html with ejs code for body>
</body>
</html>
Yes. Partials accept arguments to be passed, and they are rendered before being inserted into the calling layout.
controller:
res.view( {
layout:<yourCustomLayoutIfNeeded>,
mainContent: <mainContentObject>,
partialContent: <partialContentObject>
});
yourCustomLayoutIfNeeded:
<%- partial(<pathToPartial>, partialContent) %>
<mainContent>

About some tags in rails program

i have got this program in ruby editor.My output comes out to be
<html>
<head><title> Ruby on Rails tutorial Sample App | <%= #title %></title>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
what is the error here and what is yield and csrf_meta_tag?
You don't seem to be using a server to render the views, it seems like you are rather loading the html directly on your browser.
Maybe the following link will help you get started:
http://guides.rubyonrails.org/getting_started.html
you need to rename your file from:
application.html to be application.html.erb so that it is going to interpret your embedded ruby commands.
Ref yield & content_for
Within the context of a layout, yield identifies a section where content from the view should be inserted. The simplest way to use this is to have a single yield, into which the entire contents of the view currently being rendered is inserted:
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
You can also create a layout with multiple yielding regions:
<html>
<head>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html>
The main body of the view will always render into the unnamed yield. To render content into a named yield, you use the content_for method.

Resources