I'm implementing HTML templating in a Ruby project (non-rails). To do this I'll be using ERB, but I have some concerns about the binding stuff.
First out, this is the method I got so far:
def self.template(template, data)
template = File.read("#{ENV.root}/app/templates/#{template}.html.erb")
template_binding = binding.clone
data.each do |k, v|
template_binding.local_variable_set(k, v)
end
ERB.new(template).result(template_binding)
end
To call it I'll just do
Email.template('email/hello', {
name: 'Bill',
age: 41
}
There are two issues with the current solution though.
First, I'm cloning the current binding. I want to create a new one. I tried Class.new.binding to create a new, but since binding is a private method it can't be obtained that way.
The reason I want a new one is that I want to avoid the risk of instance variables leaking into or out from the ERB file (cloning only takes care of the latter case).
Second, I want the variables passed to the ERB file to be exposed as instance variables. Here I tried with template_binding.instance_variable_set, passing the plain hash key k which complained that it wasn't a valid instance variable name and "@#{k}", which did not complain but also didn't get available in the ERB code.
The reason I want to use instance variables is that it's a convention that the people relying on this code is familiar with.
I have checked some topics here at Stack Overflow such as Render an ERB template with values from a hash, but the answers provided does not address the problems I'm discussing.
So in short, like the title: How to create new binding and assign instance variables to it for availability in ERB?