У меня есть строковый шаблон как показано ниже
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
Существует ли лучший подход к решению этой проблемы?
Я использовал фрагмент HTML в примере кода выше для демонстрации моего сценария. Мой реальный сценарий имеет набор шаблонов XPath в конфигурационном файле. Связывать переменными в шаблоне заменяют для получения допустимой строки XPath.
Я думал об использовании ERB, но отклонил, поскольку это могло бы быть излишество.
Вы можете отобразить строку, как если бы она была шаблоном erb. Видя, что вы используете это в задаче с граблями, вам лучше использовать Erb.new.
template = '<p class="foo"><%=content%></p>'
html = Erb.new(template).result(binding)
Использование первоначально предложенных методов ActionController включает создание экземпляра объекта ActionController :: Base и отправку render или render_to_string.
Я не могу сказать, что действительно рекомендую любой из этих подходов. Для этого нужны библиотеки, такие как erb, и они были тщательно протестированы для всех крайних случаев, о которых вы еще не думали. А все, кому придется прикоснуться к вашему коду, будут вам благодарны. Однако, если вы действительно не хотите использовать внешнюю библиотеку, я включил несколько рекомендаций.
Включенный вами метод my_eval
у меня не работал. Попробуйте вместо этого что-нибудь вроде этого:
template = '<p class="foo">#{content}</p>'
def my_eval( template, content )
eval %Q{"#{template.gsub(/"/, '\"')}"}
end
Если вы хотите обобщить это так, чтобы вы могли использовать шаблоны, которые имеют переменные, отличные от содержимого
, вы можете расширить его примерно до следующего:
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' )
Но, опять же, я бы не советовал в данном случае использовать собственный.