【发布时间】:2015-08-12 10:02:24
【问题描述】:
写一个title_tag helper,我想要下面的yml文件结构
index: Hello {{@game.name}}
edit: Edit {{@game.name}} - {{@game.classification}}
到那时我采用 I18n 翻译字符串,需要用实际上下文替换 {{var}}。
title = I18n.t "title_tags.#{namespace}.#{controller_name}.#{action_name}", default: ""
title.scan(/\{\{.*?\}\}/).each do |replace|
# transform {{@game.name}} => @game.name
var = replace.gsub(/\{|\}/, "")
title.gsub! replace, eval(var)
end
这很好用。另一方面,用户可能会上传一些名称为“system(rm -rf /*)”的游戏,这可能会给我们带来真正的危险?
是否有任何可能以更安全的方式运行?
编辑
感谢 Axel,我可以用这些很酷的东西结束
title.scan(/\{\{.*?\}\}/).each do |replace|
var = replace.gsub(/\{|\}/, "")
# catch "resource" (like resource-controller)
if var.starts_with? "resource"
@tempresource = resource
var.gsub!("resource", "@tempresource")
end
# @game or @game.name
if var.starts_with?("@")
content = var.split('.').inject(nil){|clazz, method| clazz.nil? ? instance_variable_get(method) : clazz.send(method)}
title.gsub! replace, content
end
end
工作出色!
【问题讨论】:
-
我了解液体并阅读了 parser.rb 的代码。无法真正弄清楚他们是如何做到的。看起来他们编写了一个自己的函数,可以与 eval 相媲美。也许你有更深的洞察力。顺便说一句:为walle欢呼:-)
-
我想建议你只是在你的项目中使用 Liquid,而不是自己重新实现它;-)
-
那是“显而易见的”。很明显我已经尝试过 Liquid::Template.parse("Hallo {{@game.name}}").render 正在返回“Hallo”。也许我弄错了如何使用液体。
标签: ruby-on-rails ruby