Note: I'm not using rails, sinatra, or tilt, just ruby's built in ERB.
Suppose I have two erb files:
file1.erb:
Start
<%= yield if block_given? -%>
End
and file2.erb:
<% render('file1.erb') do %>
Some text
<% end %>
I'd like to get output that looks like:
Start
Some text
End
However, with the following ruby code:
require 'erb'
def render(file)
content = File.read(file)
b = binding
ERB.new(content, trim_mode: '-').result b
end
res = render('file2.erb')
I only get "Some Text". And if I change the first line of file2.erb to use <%= instead of <% then I get a syntax error:
Traceback (most recent call last):
3: from test.rb:9:in `<main>'
2: from test.rb:6:in `render'
1: from /usr/lib/ruby/2.7.0/erb.rb:905:in `result'
/usr/lib/ruby/2.7.0/erb.rb:905:in `eval': (erb):1: syntax error, unexpected ')' (SyntaxError)
...t.<<(( render('file1.erb') do ).to_s); _erbout.<< "\\n Some T...
... ^
(erb):3: syntax error, unexpected `end', expecting ')'
; end ; _erbout.<< "\\n".freeze
^~~
(erb):4: syntax error, unexpected end-of-input, expecting ')'
Is there some way to get this to work with the 'erb' module?
I can get the yielding to work if I use a block that returns an expression directly, but that won't work for my case.
Another answer has a solution where the calling code can render a template inside a different layout. But that doesn't really work for me, because I need to define the layout to use inside the template itself (there isn't really an equivalent of a controller in my code).
I thought of maybe doing something like, changing .result to .run, and running it like:
$stdout = outstream
render('file2.erb')
But for some reason the results in the output:
Start
Some Text
End
Some Text
Note the extra "Some Text" at the end.