Including One Erb File into Another

Including one erb file into another

ERB templates can be nested by evaluating the sub-template from within <%= %> of the main template.

<%= ERB.new(sub_template_content).result(binding) %>

For example:

require "erb"

class Page
def initialize title, color
@title = title
@color = color
end

def render path
content = File.read(File.expand_path(path))
t = ERB.new(content)
t.result(binding)
end
end

page = Page.new("Home", "#CCCCCC")
puts page.render("home.html.erb")

home.html.erb:

<title><%= @title %></title>
<head>
<style type="text/css">
<%= render "home.css.erb" %>
</style>
</head>

home.css.erb:

body {
background-color: <%= @color %>;
}

produces:

<title>Home</title>
<head>
<style type="text/css">
body {
background-color: #CCCCCC;
}
</style>
</head>

How to include erb file on another?

You are looking for render:

<%= render('file_folder/other_file') %>

Note, that you can omit .html.erb part of the file name.

Include same js file in multiple html.erb files in Rails

No, normally the javascript code is not available in the other views, just in the one where you include it. So you need to include it again.

The exception would be if you have it in a layout file like application.html.erb because this on is rendered in all views.

If you call the javascript package in both partials anyway, then you can also just call it in main, after the if statement. This will be loaded after the partials have been loaded. It might seem weird, to require a piece javascript in a file that doesn't seem to have the html elements that you are using in the JS file, however, the partials are just a way to organise the code in rails. In the end they will be merged into one big html file.

In the comments you said this if statement is nested into another if statement, so maybe you don't need the javascript at all? Paste it at the end of the if statement like so

<% if outer_if_statment %>
<% if some_condition %>
<% render partial: 'first_partial' %>
<% elsif some_other_condition %>
<% render partial: 'second_partial' %>
<% else %>
<% render partial: 'first_partial' %>
<% render partial: 'second_partial' %>
<% end %>
<%= javascript_include_tag 'common' %>
<% else %>
...
<% end %>

This way it will be available in for all partials but not, if the inner if statement is not chosen.

Another thing:
Javascript should be loaded at the end of the html file anyway so that the user doens't have to wait for it to load while he/she doesn't see any html elements. If we put the javascript right in the middle of a hmtl file like this, we're infringing this principle.

Now there is a helper to that:
You can define a second yield in your application.html.erb

 <body>
<%= yield %>
<%= javascript_include_tag 'application' %>
<%= javascript_pack_tag 'application' %>

<%= yield(:after_js) %>
</body>

In the views, you can call it like this:

<%= content_for :after_js do %>
<%= javascript_include_tag 'common' %>
<% end %>

This will make sure, that the JS is loaded at the end of the body and that all other JS code is loaded beforehand (if there are any dependencies).
And, if you still only want to load it depending on the conditions you could repeat the if statement inside the content_for block.

Depending on what your JS script looks like, you can also make sure it only executes, if the necessary HTML element is found on the page. Let's imagine you want to add an event listener on a button.

// common.js
const button = document.querySelector("#red-button")
if (button) {
button.addEventListener(...)
}

Is it possible to load + render an html.erb file within another html.erb file?

Yes, with partials. So if you want to render _my_view.html.erb within some other view, you should insert the following:

<%= render partial: "my_view", locals: { myvar: @val } %>

Where you can pass variables to the partial through the locals hash.

Ruby method that yields one ERB template over another

I hope I got you question.
The following link should answer your question

How can I use views and layouts with Ruby and ERB (not Rails)?

Sinatra's way to render multiple .erb files

Here is what I did for mine:

get '/Login' do verbose = params['verbose']
cTest = MyTests.new("envo")
result = cTest.login()

if verbose == 'true'
erb :newResultPage, :locals => {:result => result}
elsif verbose == 'false'
erb :resultPage, :locals => {:result => result}
end
end

Basically, I use a conditional statement to determine which page to use. This one is based on parameters. You could also use return results, or what ever other conditions you like.

How to reuse ERB templating code in function?

What you are trying to do is not technically impossible, but rather difficult and not recommended as can be seen by reading comments and answers to this question.

As your error message points out your def won't quite happen in the context you "probably" expect and you certainly won't be able to "freely use erb features" while defining the method (since your context is completely different from what you expect).

The "railsy" way to do this is adding a helper or using a partial, but both come with their drawbacks. .erb files (as most templating-languages) do not "factor" well. If you want to factor things somewhat more freely you should look at the fortitude gem which provides what is basically a ruby-DSL for html which factors pretty easily. However, that is a rather drastic change from what you are probably used to.

If you really want to define a method inside an .erb-file then you would have to do it entirely within a single pair of <% ... %> brackets where you will have only access to your params, not your context. You would have to return what is basically a String in order to be able to use it in <%= ... %> and pay a hell of a lot of attention to escaping rules for everything to make it through. This is most probably more trouble than it is worth (but easy enough to do in fortitude :-).



Related Topics



Leave a reply



Submit