2010-02-23 182 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)