我必须忽略一些非常简单的东西,但我似乎无法弄清楚如何使用哈希映射中的值渲染简单的ERB模板。
我对来自python的ruby相对较新。我有一个ERB模板(不是HTML),我需要使用从哈希映射中获取的上下文来渲染,我从外部源接收。
但是,ERB的文档指出ERB.result
方法需要binding
。我了解到它们是在ruby中保存变量上下文的东西(类似于locals()
和globals()
在python中,我猜想?)。但是,我不知道如何从哈希映射中构建绑定对象。
一点点(很多,实际上)谷歌搜索给了我这个:http://refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template,它使用了一些逃避我的红宝石元编程魔法。
那么,这个问题不是一个简单的解决方案吗?或者是否有更好的模板引擎(不依赖于HTML)更适合这种情况? (我只选择了ERB,因为它在stdlib中。)
答案 0 :(得分:73)
require 'erb'
require 'ostruct'
def erb(template, vars)
ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
end
e.g
1.9.2p290 :008 > erb("Hey, <%= first_name %> <%= last_name %>", :first_name => "James", :last_name => "Moriarty")
=> "Hey, James Moriarty"
答案 1 :(得分:56)
我不知道这是否符合“更优雅”的条件:
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为模板,听起来像“凉茶”。命名很难。)
答案 2 :(得分:32)
如果您可以使用Erubis,则您已拥有此功能:
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"
答案 3 :(得分:24)
Ruby 2.5有ERB#result_with_hash
提供此功能:
$ ruby -rerb -e 'p ERB.new("Hi <%= name %>").result_with_hash(name: "Tom")'
"Hi Tom"
答案 4 :(得分:8)
这里棘手的部分不是污染与冗余局部变量的绑定(如最高评价的答案):
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)
答案 5 :(得分:6)
使用Binding的简单解决方案:
b = binding
b.local_variable_set(:a, 'a')
b.local_variable_set(:b, 'b')
ERB.new(template).result(b)
答案 6 :(得分:4)
如果您想要非常简单地执行操作,您始终可以在ERB模板中使用显式哈希查找。假设您使用“绑定”将名为“hash”的哈希变量传递到模板中,它将如下所示:
<%= hash["key"] %>