code ruby erb template-engine

code - erb ruby html



Renderiza una plantilla ERB con valores de un hash (7)

Debo estar pasando por alto algo muy simple aquí, pero parece que no consigo encontrar una plantilla ERB simple con valores de un hash-map.

Soy relativamente nuevo en el rubí, viniendo de python. Tengo una plantilla ERB (no HTML), que necesito renderizar con el contexto que se debe tomar de un hash-map, que recibo de una fuente externa.

Sin embargo, la documentación de ERB, establece que el método ERB.result toma un binding . Aprendí que son algo que mantiene los contextos variables en ruby ​​(algo así como locals() y globals() en python, supongo?). Pero, no sé cómo puedo construir un objeto de enlace de mi hash-map.

Un poco ( mucho , en realidad) de Google me dio esto: http://refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template , que usa algo de magia de metaprogramación rubí que se me escapa

Entonces, ¿no hay una solución simple para este problema? ¿O hay un motor de plantillas mejor (no vinculado a HTML) más adecuado para esto? (Solo elegí ERB porque está en el stdlib).


La parte difícil aquí no es contaminar el enlace con variables locales redundantes (como en las respuestas más valoradas):

require ''erb'' class TemplateRenderer def self.empty_binding binding end def self.render(template_content, locals = {}) b = empty_binding locals.each { |k, v| b.local_variable_set(k, v) } # puts b.local_variable_defined?(:template_content) #=> false ERB.new(template_content).result(b) end end # use it TemplateRenderer.render(''<%= x %> <%= y %>'', x: 1, y: 2) #=> "1 2" # use it 2: read template from file TemplateRenderer.render(File.read(''my_template.erb''), x: 1, y: 2)


No sé si esto califica como "más elegante" o no:

require ''erb'' require ''ostruct'' class ErbalT < OpenStruct def render(template) ERB.new(template).result(binding) end end et = ErbalT.new({ :first => ''Mislav'', ''last'' => ''Marohnic'' }) puts et.render(''Name: <%= first %> <%= last %>'')

O a partir de un método de clase:

class ErbalT < OpenStruct def self.render_from_hash(t, h) ErbalT.new(h).render(t) end def render(template) ERB.new(template).result(binding) end end template = ''Name: <%= first %> <%= last %>'' vars = { :first => ''Mislav'', ''last'' => ''Marohnic'' } puts ErbalT::render_from_hash(template, vars)

(ErbalT tiene Erb, T para la plantilla y suena como "té de hierbas". Nombrar cosas es difícil).


Ruby 2.5 tiene ERB#result_with_hash que proporciona esta funcionalidad:

$ ruby -rerb -e ''p ERB.new("Hi <%= name %>").result_with_hash(name: "Tom")'' "Hi Tom"


Si desea hacer las cosas de manera muy simple, siempre puede usar búsquedas de hash explícitas dentro de la plantilla ERB. Digamos que usa "enlace" para pasar una variable de hash llamada "hash" a la plantilla, se vería así:

<%= hash["key"] %>


Si puedes usar Erubis ya tienes esta funcionalidad:

irb(main):001:0> require ''erubis'' #=> true irb(main):002:0> locals = { first:''Gavin'', last:''Kistner'' } #=> {:first=>"Gavin", :last=>"Kistner"} irb(main):003:0> Erubis::Eruby.new("I am <%=first%> <%=last%>").result(locals) #=> "I am Gavin Kistner"


Solución simple utilizando Binding :

b = binding b.local_variable_set(:a, ''a'') b.local_variable_set(:b, ''b'') ERB.new(template).result(b)


require ''erb'' require ''ostruct'' def erb(template, vars) ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding }) end

p.ej

1.9.2p290 :008 > erb("Hey, <%= first_name %> <%= last_name %>", :first_name => "James", :last_name => "Moriarty") => "Hey, James Moriarty"