2010-02-23 11 views
8

tengo una plantilla de cadena como se muestra a continuaciónEvaluación de las plantillas de cadena

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

que quieren evaluar la plantilla basada en el valor actual de la variable llamada content.

html = my_eval(template, "Hello World") 

Este es mi enfoque actual para este problema:

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

¿Hay un mejor enfoque para resolver este problema?

EDITAR

que utilizan fragmento HTML en el código de ejemplo anterior para demostrar mi escenario. Mi escenario real tiene un conjunto de plantillas XPATH en un archivo de configuración. Las variables de vinculación en la plantilla se sustituyen para obtener una cadena XPATH válida.

He pensado en usar ERB, pero he decidido no hacerlo ya que podría ser una exageración.

Respuesta

11

Puede representar una cadena como si fuera una plantilla erb. Al ver que estás usando esto en una tarea de rake, es mejor que utilices Erb.new.

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

Utilizando los métodos sugeridos originalmente ActionController, implica crear instancias de un objeto ActionController :: Base y el envío de render o render_to_string.

+0

Utilicé un fragmento de HTML en la plantilla para demostrar el escenario. Tengo un montón de cadenas XPATH que necesitan sustitución. Había pensado en utilizar ERB, pero quería algo ligero. –

+0

Debo decir que esta es una solución intrigante. Tengo que ejecutar mi código en una tarea de rake. Entonces esta solución podría necesitar algunos ajustes. –

+0

Si está hablando de una tarea de rake, es mejor utilizar Erb.new en lugar del render de ActionController #. Solución actualizada para reflejar eso. – EmFi

3

No puedo decir que realmente recomiendo cualquiera de estos enfoques. Esto es para lo que son las bibliotecas como erb, y han sido probadas exhaustivamente para todos los casos extremos en los que aún no has pensado. Y todos los demás que tengan que tocar tu código te lo agradecerán. Sin embargo, si realmente no desea usar una biblioteca externa, he incluido algunas recomendaciones.

El método my_eval que incluyó no funcionó para mí. Pruebe algo como esto en su lugar:

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

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

Si desea generalizar esta esto para que pueda utilizar las plantillas que tienen variables distintas de content, se podría ampliar a algo como esto:

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

Ese método se llama así

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

Pero una vez más, te aconsejo que no ruede su propio en este caso.

19

Puede hacer lo que quiera con el método nativo de cadena '%':

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

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

+0

Mind_completely_blown.gif – Trip

+1

Esta es la mejor respuesta. – WattsInABox

+1

Puede valer la pena agregar que con este método puede tener 'marcadores de posición nombrados, es decir '" Perfil:% {nombre},% {edad} "% {nombre:' Juan ', edad: 25}' – mrt

0

Ésta es también una agradable:

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

Hasta tarde, pero creo que una mejor manera es como ruby-style-guide:

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