Оценка строковых шаблонов - PullRequest
8 голосов
/ 23 февраля 2010

У меня есть шаблон строки, как показано ниже

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, но решил отказаться, поскольку это может быть излишним.

Ответы [ 5 ]

21 голосов
/ 09 ноября 2010

Вы можете делать то, что хотите, с помощью нативного метода String '%':

> 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

11 голосов
/ 24 февраля 2010

Вы можете отобразить строку, как если бы это был шаблон erb. Видя, что вы используете это в граблях, вам лучше использовать Erb.new.

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

Использование первоначально предложенных методов ActionController включает создание экземпляра объекта ActionController :: Base и отправку render или render_to_string.

3 голосов
/ 24 февраля 2010

Не могу сказать, что действительно рекомендую любой из этих подходов. Это то, для чего предназначены библиотеки типа 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' )

Но, опять же, я бы посоветовал не катать свои собственные в этом случае.

0 голосов
/ 01 июня 2017

Поздно, но я думаю, что лучший способ - это ruby-style-guide :

template     = '<p class="foo">%<content>s</p>'
content_text = 'Text inside p'
output = format( template , content: content_text ) 
0 голосов
/ 12 марта 2014

Это тоже неплохо:

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.

больше здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...