Render an ERB template with values from a hash
require 'erb'
require 'ostruct'
def render(template, vars)
ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
end
e.g
render("Hey, <%= first_name %> <%= last_name %>", first_name: "James", last_name: "Moriarty")
# => "Hey, James Moriarty"
Update:
A simple example without ERB:
def render(template, vars)
eval template, OpenStruct.new(vars).instance_eval { binding }
end
e.g.
render '"Hey, #{first_name} #{last_name}"', first_name: "James", last_name: "Moriarty"
# => "Hey, James Moriarty
Update 2: checkout @adam-spiers comment below.
If you can use Erubis you have this functionality already:
irb(main):001:0> require 'erubis'
#=> true
irb(main):002:0> locals = { first:'Gavin', last:'Kistner' }
#=> {:first=>"Gavin", :last=>"Kistner"}
irb(main):003:0> Erubis::Eruby.new("I am <%=first%> <%=last%>").result(locals)
#=> "I am Gavin Kistner"
I don't know if this qualifies as "more elegant" or not:
require 'erb'
require 'ostruct'
class ErbalT < OpenStruct
def render(template)
ERB.new(template).result(binding)
end
end
et = ErbalT.new({ :first => 'Mislav', 'last' => 'Marohnic' })
puts et.render('Name: <%= first %> <%= last %>')
Or from a class method:
class ErbalT < OpenStruct
def self.render_from_hash(t, h)
ErbalT.new(h).render(t)
end
def render(template)
ERB.new(template).result(binding)
end
end
template = 'Name: <%= first %> <%= last %>'
vars = { :first => 'Mislav', 'last' => 'Marohnic' }
puts ErbalT::render_from_hash(template, vars)
(ErbalT has Erb, T for template, and sounds like "herbal tea". Naming things is hard.)
Ruby 2.5 has ERB#result_with_hash which provides this functionality:
$ ruby -rerb -e 'p ERB.new("Hi <%= name %>").result_with_hash(name: "Tom")'
"Hi Tom"