Display ERB Template with Hash Values

I need to skip something very simple here, but I cannot figure out how to make 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) that I need to display using the context that I need to take from the hash map that I get from an external source.

However, the ERB documentation states that the ERB.result method accepts binding . I found out that they are context variables in ruby ​​(something like locals() and globals() in python, I suppose?). But I do not know how I can build a binding object from my hash map.

A bit (much, actually) googling gave me this: http://refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template , which uses ruby ​​metaprogramming magic, which eludes me.

So, isn't there a simple solution to this problem? Or is there a better template engine (not tied to HTML) that is better suited for this? (I chose only ERB because its in stdlib).

+47
ruby template-engine erb
Jan 21 '12 at 16:41
source share
7 answers

I don’t know if this matches the “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 the pattern and sounds like “herbal tea.” Naming things is complicated.)

+51
Jan 21 '12 at 17:40
source share
 require 'erb' require 'ostruct' def erb(template, vars) ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding }) end 

eg

 1.9.2p290 :008 > erb("Hey, <%= first_name %> <%= last_name %>", :first_name => "James", :last_name => "Moriarty") => "Hey, James Moriarty" 
+66
Mar 16 2018-12-12T00:
source share

If you can use Erubis , you already have this function:

 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" 
+31
Jan 21 '12 at 18:39
source share

A simple solution using Binding :

 b = binding b.local_variable_set(:a, 'a') b.local_variable_set(:b, 'b') ERB.new(template).result(b) 
+6
Jan 18 '15 at 2:57
source share

The hard part here is not to pollute the binding with redundant local variables (e.g. in the most popular answers):

 require 'erb' class TemplateRenderer def self.empty_binding binding end def self.render(template_content, locals = {}) b = empty_binding locals.each { |k, v| b.local_variable_set(k, v) } # puts b.local_variable_defined?(:template_content) #=> false ERB.new(template_content).result(b) end end # use it TemplateRenderer.render('<%= x %> <%= y %>', x: 1, y: 2) #=> "1 2" # use it 2: read template from file TemplateRenderer.render(File.read('my_template.erb'), x: 1, y: 2) 
+4
Jun 14 '16 at 21:33
source share

If you want to do something very simply, you can always just use explicit hash requests inside the ERB template. Suppose you use a "binding" to pass a hash variable called a "hash" into the template, it will look like this:

 <%= hash["key"] %> 
+3
Jan 21 '12 at 17:25
source share

Ruby 2.5 has an ERB#result_with_hash that provides this functionality:

 $ ruby -rerb -e 'p ERB.new("Hi <%= name %>").result_with_hash(name: "Tom")' "Hi Tom" 
+3
May 30 '17 at 15:45
source share



All Articles