I must be overlooking something very simple here but I can't seem to figure out how to render a simple ERB template with values from a hash-map.
I am relatively new to ruby, coming from python. I have an ERB template (not HTML), which I need rendered with context that's to be taken from a hash-map, which I receive from an external source.
However, the documentation of ERB, states that the ERB.result
method takes a binding
. I learnt that they are something that hold the variable contexts in ruby (something like locals()
and globals()
in python, I presume?). But, I don't know how I can build a binding object out of my hash-map.
A little (a lot, actually) googling gave me this: http://refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template, which uses some ruby metaprogramming magic that escapes me.
So, isn't there a simple solution to this problem? Or is there a better templating engine (not tied to HTML) better suited for this? (I only chose ERB because its in the stdlib).
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.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With