Reputation: 10350
What we are trying to do is to store a chunk of erb
code in a string
and then render the code in run time
in erb.
Here is the chunk of erb code which is stored as string:
<tr>
<th>#</th>
<th><%= t('Date') %></th>
<th><%= t('Project Name') %></th>
<th><%= t('Task Name') %></th>
<th><%= t('Log') %></th>
<th><%= t('Entered By') %></th>
</tr>
<% @logs.each do |r| %>
<tr>
<td><%= r.id %></td>
<td><%= (r.created_at + 8.hours).strftime("%Y/%m/%d")%></td>
<td><%= prt(r, 'task.project.name') %></td>
<td><%= prt(r, 'task.task_template.task_definition.name') %></td>
<td><%= prt(r, :log) %></td>
<td><%= prt(r, 'last_updated_by.name') %></td>
</tr>
<% end %>
t() is the translation method for internationalization.
How can we insert the above erb code stored in string back to erb file below for rendering (in pseud code) ?
<table class="table table-striped">
<% erb_code = retrieve(chunk_of_erb_code)%>
<% erb_code here for rendering %>
</table>
Is there a solution for the problem? Thanks for help.
UPDATE:
Working code with render inline
(by kamesh):
<% erb_code = find_config_const('task_log_view', 'projectx')%>
<%= render inline: ERB.new(erb_code).result(binding) %>
For a good practice, variable erb_code could be moved into the controller.
Upvotes: 1
Views: 4877
Reputation: 471
I think i got your question. you can append any html string in erb using in view:
<%= render inline:"<p>new Field</p>"%>
or
<%= render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>" %>
or in controller as:
render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>"
writing it in any _xyz.html.erb or xyz.html.erb and also can be used from controller, as well. for more check following link. in sub topic - 2.2.6 Using render with :inline. rails guide
I have checked working of this. Let me know in case of any issue.
Upvotes: 4
Reputation: 48589
(I was able to simplify my original answer quite a bit.)
You can create application helpers like this:
helpers/application_helper.rb:
module ApplicationHelper
def my_erb_converter(template)
erb = ERB.new(template)
erb.result
end
def t(str)
"***#{str}***"
end
end
Then in an action do:
include ApplicationHelper
class SomeController < ApplicationController
...
...
def some_action
@html = my_erb_converter("<div><%= t('hello') %></div>")
...
end
Then in your view:
<table class="table table-striped">
<%= raw @html %>
</table>
This also works for me:
module ApplicationHelper
def convert_erb(template)
erb = ERB.new(template)
erb.result
end
def t(str)
"***#{str}***"
end
def get_erb
"<div><%= t('hello') %></div>"
end
end
View:
<table class="table table-striped">
<%= raw convert_erb(get_erb) %>
</table>
Upvotes: 1
Reputation: 14740
Seems like a job for partials.
# app/views/some_folder/_my_erb_partial
<%= t(whatever) %>
...
<table class="table table-striped">
<%= render 'some_folder/my_erb_partial' %>
</table>
Update.
If you need to store ERB templates in your database and render them in real time, take a look at render erb from database into view problem please help!
However, I don't know if this is necessarily your best option, as it could lead to security issues and other issues (namely, if you change code, your templates stored in the database would likely break). In most cases, it would be best just to make a new model for whatever you need to do, and do it the Rails way (with partials).
Upvotes: 1
Reputation: 13181
You definitely want to do it with partials or helpers, because the solution you are requesting for is complicated and confusing.
But if you really need to implement this solution, you would have to create a .html.erb.erb file, it would be interpreted by erb twice.
Given the following helpers
def print_one
"1"
end
def print_a_method
"<%= print_one %>"
end
Pass 1, RoR interpret the html.erb.erb file, which originally look like this:
<%= "<%=" %> print_one.to_i + print_one.to_i <%= "%>" %>
<%= print_a_method %>
<%= 5 + 3 %>
The trick in first line is to "generate the erb tags for the second pass": <%= "<%=" %>
and <%= "%>" %>
that will become <%=
and %>
, and the rest of the first line is not interpreted during pass 1.
On the other hand the second line will be entirely interpreted during this pass, and the output of print_a_method
will be placed in the file for it to be interpreted during the second pass.
The third line is interpreted as well and output its result.
Pass 2, RoR takes the result of the first pass which is now a .html.erb file. Internally it would look like this
# As you can seem the erb tags was generated, and now the erb code is ready for pass 2
<%= print_one.to_i + print_one.to_i %>
# The second line was interpreted and its result is erb code that will be interpreted during pass 2
<%= print_one %>
# the third line was interpreted and give the following output
8
Final render would be the .html file where the file from pass 2 is interpreted and that would look like this
2
1
8
Upvotes: 1