2010-02-23 126 views
8

我有一个字符串模板,如下图所示评估字符串模板

template = '<p class="foo">#{content}</p>' 

我想基于称为content变量的当前值来评估模板。

html = my_eval(template, "Hello World") 

这是我目前对这个问题的办法:

def my_eval template, content 
    "\"#{template.gsub('"', '\"')}\"" # gsub to escape the quotes 
end 

是否有解决这个问题的一个更好的办法?

EDIT

我用HTML片段在上面的示例代码以证明我的方案。我的真实场景是在配置文件中设置了XPATH模板。模板中的绑定变量将被替换以获取有效的XPATH字符串。

我曾考虑过使用ERB,但由于它可能是一个矫枉过正的决定。

回答

11

你可以渲染一个字符串,就好像它是一个erb模板。看到你在耙子任务中使用它,你最好使用Erb.new。

template = '<p class="foo"><%=content%></p>' 
html = Erb.new(template).result(binding) 

使用最初建议的ActionController的方法,包括实例化的ActionController :: Base的对象,并发送渲染或render_to_string。

+0

我在模板中使用HTML片段来演示场景。我有一堆需要替换的XPATH字符串。我曾想过使用ERB,但我想要一些轻量级的东西。 – 2010-02-23 21:35:06

+0

我必须说这是一个有趣的解决方案。我必须在rake任务中运行我的代码。所以这个解决方案可能需要一些调整。 – 2010-02-23 21:52:57

+0

如果你正在谈论rake任务,你最好使用Erb.new而不是ActionController#render。解决方案更新以反映这一点 – EmFi 2010-02-23 22:02:59

3

我不能说我真的推荐这些方法。这就是像erb这样的库,它们已经通过了所有你还没有想到的边缘情况的测试。而其他所有需要触摸代码的人都会感谢你。但是,如果你真的不想使用外部库,我已经包含了一些建议。

您包含的my_eval方法对我无效。尝试这样的事情,而不是:

template = '<p class="foo">#{content}</p>' 

def my_eval(template, content) 
    eval %Q{"#{template.gsub(/"/, '\"')}"} 
end 

如果要概括这个这个,所以你可以使用具有比content其他变量的模板,你可以将它扩展到这样的事情:

def my_eval(template, locals) 
    locals.each_pair{ |var, value| eval "#{var} = #{value.inspect}" } 
    eval %Q{"#{template.gsub(/"/, '\"')}"} 
end 

这种方法将被称为这样

my_eval('<p class="foo">#{content}</p>', :content => 'value of content') 

但是,我再次建议不要在这种情况下滚动自己。

19

你可以做你想做的与字符串的本地方法 '%':

> template = "<p class='foo'>%s</p>" 
> content = 'value of content' 
> output = template % content 
> puts output 
=> "<p class='foo'>value of content</p>" 

http://ruby-doc.org/core/classes/String.html#M000770

+0

Mind_completely_blown.gif – Trip 2013-08-03 14:50:38

+1

这是更好的答案。 – WattsInABox 2013-08-28 00:59:55

+1

值得一提的是,使用这种方法你可以有'命名的占位符,即''Profile:%{name},%{age}“%{name:'John',age:25}' – mrt 2015-06-25 13:10:41

0

这也是一个很好的一个:

template = "Price of the %s is Rs. %f." 
# %s - string, %f - float and %d - integer 

p template % ["apple", 70.00] 
# prints Price of the apple is Rs. 70.000000. 

more here

0

要迟到了,但我认为更好的方法就像ruby-style-guide

template  = '<p class="foo">%<content>s</p>' 
content_text = 'Text inside p' 
output = format(template , content: content_text)