<%= title "Appending to ERB output" %>I use ERB to generate both .doc and .html files. If I generate an html file the above template will produce the html found below.
<title>Appending to ERB output</title>This is very straightforward stuff easily handled by ERB. I use classes and bindings for my needs, but the example below is a simplified version that should get the point across.
require 'erb'I recently ran into a different situation that took a bit more effort. In the material I was writing up I needed a sidebar. I thought that the best way to represent the sidebar in my template was to use a block. Using a block ensures that the sidebar, when generating html, will be properly closed by requiring an "end".
template = <<eos
<%= title "Appending to ERB output" %>
eos
def title(text)
"<title>#{text}</title>"
end
puts ERB.new(template).result
<%= title "Appending to ERB output" %>Adding the content from the sidebar to the output is easily achieved by calling "yield".
<% sidebar do %>
sidebar content
<% end %>
require 'erb'However, the above implementation hasn't appended any tags to mark the beginning or end of the sidebar. Based on the way that the title method works you might assume that the following would work.
template = <<eos
<%= title "Appending to ERB output" %>
<% sidebar do %>
sidebar content
<% end %>
eos
def sidebar
yield
end
def title(text)
"<title>#{text}</title>"
end
puts ERB.new(template).result
require 'erb'But, the above code does not produce any div tags. This is because <%= .. %> mark ruby expressions that are replaced with the result of the expression, and we used <% .. %> which is used to evaluate ruby code but not append.
template = <<eos
<%= title "Appending to ERB output" %>
<% sidebar do %>
sidebar content
<% end %>
eos
def sidebar
"<div border=1>#{yield}</div>"
end
def title(text)
"<title>#{text}</title>"
end
A way to solve this issue is to tell ERB where to store the output. ERB allows you to specify, as a constructor argument, a variable to store the output in. This allows you to append to the output from within a block declaration.
require 'erb'The above code produces the following result.
template = <<eos
<%= title "Appending to ERB output" %>
<% sidebar do %>
sidebar content
<% end %>
eos
def sidebar
@output << "<div border=1>"
yield
@output << "</div>"
end
def title(text)
"<title>#{text}</title>"
end
ERB.new(template, nil, nil, "@output").result
puts @output
<title>Appending to ERB output</title>
<div border=1>
sidebar content
</div>
I like the wat it was solved in Rails: it has capture helper that extracts output generated by block from ERb output buffer and returns it as string.
ReplyDeleteUsing this helper, sidebar method could look like this:
def sidebar(&block)
content = capture(&block)
"<div>#{content}</div>"
end
It uses ERb black magic too, but it allows to keep this magic in a separate place.
Sorry a little of topic but what blog tempelete are u using ?
ReplyDeleteThe template I'm using is a modified version of Herbert.
ReplyDelete