使用散列中的值呈现ERB模板

我必须在这里忽略一些非常简单的东西,但我似乎无法弄清楚如何使用哈希映射中的值来呈现简单的ERB模板。

来自python的ruby我相对较新。 我有一个ERB模板(不是HTML),我需要使用从外部源接收的哈希映射获取上下文。

但是,ERB的文档声明ERB.result方法需要binding 。 我知道他们是在Ruby中保存variables上下文的东西(类似于Python中的locals()globals() ,我认为?)。 但是,我不知道如何从我的哈希映射中构build一个绑定对象。

一个( 很多 ,实际上)谷歌搜查给了我这个: http : //refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template ,它使用了一些ruby元编程魔术逃避我

那么,这个问题不是一个简单的解决scheme吗? 还是有更好的模板引擎(不绑定到HTML)更适合这个? (我只select了ERB,因为它在stdlib中)。

我不知道这是否“更优雅”的资格:

 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 %>') 

或者从一个类的方法:

 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有Erb,T为模板,听起来像“凉茶”,命名很难)

 require 'erb' require 'ostruct' def erb(template, vars) ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding }) end 

例如

 1.9.2p290 :008 > erb("Hey, <%= first_name %> <%= last_name %>", :first_name => "James", :last_name => "Moriarty") => "Hey, James Moriarty" 

如果你可以使用Erubis,你已经有了这个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" 

简单的解决scheme使用绑定 :

 b = binding b.local_variable_set(:a, 'a') b.local_variable_set(:b, 'b') ERB.new(template).result(b) 

这里棘手的部分是不要污染与冗余局部variables的绑定(如在顶级答案中):

 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) 

如果你想做的事情很简单,你总是可以在ERB模板中使用显式的哈希查找。 假设您使用“绑定”将名为“hash”的哈希variables传递给模板,它将如下所示:

 <%= hash["key"] %> 

Ruby的下一个主要版本有ERB#result_with_hash ,它提供了这个function; 在2017年5月30日的主干上:

 $ ruby -rerb -e 'puts RUBY_VERSION ; puts ERB.new("Hi <%= name %>").result_with_hash(name: "Tom")' 2.5.0 Hi Tom