2012-04-19 23 views
19

Estoy escribiendo una herramienta de línea de comandos que finalmente generará un informe HTML. La herramienta está escrita en Ruby. (No estoy usando Rails). Intento mantener la lógica de la aplicación en un conjunto de archivos y las plantillas HTML (los archivos .erb) en otro conjunto.Incluyendo un archivo erb en otro

Aunque estoy teniendo un problema realmente molesto: no puedo incluir con éxito un archivo .erb en otro.

Para ser más específicos, que estoy tratando de hacer algo como esto (en pseudo-código):

<html> 
<head> 
    <style type='text/css'> 
    [include a stylesheet here] 
    [and another one here] 
    </style> 
</head> 
<body> 
    <p>The rest of my document follows... 

Ese fragmento de ejemplo es en sí un archivo erb, que está siendo invocado desde dentro de la aplicación lógica.

Estoy haciendo las cosas de esta manera para poder mantener mis hojas de estilo fuera de la plantilla principal para que sea más fácil/más limpio mantener la aplicación. El producto final (el informe), sin embargo, debe ser un único archivo HTML independiente que no tenga dependencias y, por lo tanto, quiero alinear esas hojas de estilo en el encabezado del documento cuando se genera el informe.

Parece que esto debería ser fácil, pero he estado golpeando mi cabeza contra la pared (y buscando en Google, y RTMF) durante la última hora, y no estoy teniendo ninguna suerte en absoluto.

¿Cómo se supone que se debe hacer? Gracias.

Respuesta

31

Las plantillas de ERB se pueden anidar mediante la evaluación de la sub-plantilla dentro de <% =%> de la plantilla principal.

<%= ERB.new(sub_template_content).result(binding) %> 

Por ejemplo:

require "erb" 

class Page 
    def initialize title, color 
    @title = title 
    @color = color 
    end 

    def render path 
    content = File.read(File.expand_path(path)) 
    t = ERB.new(content) 
    t.result(binding) 
    end 
end 

page = Page.new("Home", "#CCCCCC") 
puts page.render("home.html.erb") 

home.html.erb:

<title><%= @title %></title> 
<head> 
    <style type="text/css"> 
<%= render "home.css.erb" %> 
    </style> 
</head> 

home.css.erb:

body { 
    background-color: <%= @color %>; 
} 

produce:

<title>Home</title> 
<head> 
    <style type="text/css"> 
body { 
    background-color: #CCCCCC; 
} 
    </style> 
</head> 
+0

No estoy trabajando en Rails, así que no * pienso * que las cosas de 'render' se aplican a mí (podrían estar equivocadas), pero esa primera línea funcionaba como un campeón. ¡Muchas gracias! –

+3

El método de renderización se definió en el ejemplo anterior utilizando pure std ruby, por lo que se puede usar en un entorno sin raíles. Aclamaciones. – cydparser

+0

Ha, wow. No sé cómo no me di cuenta de eso. Gracias por señalarlo y gracias por la solución. Funcionó perfectamente. –

6
<%= ERB.new(sub_template_content).result(binding) %> 

no funciona, cuando se utiliza erb utilidad CLI, múltiples _erbout variables son invalidados y sólo se utiliza último.

utilizar de esta manera:

<%= ERB.new(sub_template_content, eoutvar='_sub01').result(binding) %> 
+3

Necesitaba hacer 'ERB.new (sub_template_context, nil, nil, '_sub01'). Result (binding)' cuando usa Test Kitchen. Debe usar una versión anterior de ruby ​​o algo así. – Jack

+0

Creo que estaba usando Ruby 1.8 al agregar esta respuesta – mighq

11

estoy necesitando esto en una aplicación de Sinatra, y me parece que solo se puede llamar así de la misma manera que llamé el original:

En el Sinatra aplicación, que llamo el índice:

erb :index 

Luego, en la plantilla principal, puedo hacer lo mismo para cualquier sub-plantilla:

<div id="controls"> 
    <%= erb :controls %> 

..que muestra la plantilla 'controls.erb'.

+1

Esta es definitivamente la respuesta más fácil y, por lo tanto, la mejor. –

+2

Si pasa vars locales ('erb: index,: locals => {...}') y necesita pasar esos vars locales, puede llamar a '<% = erb (: controls, {}, lugareños)%> ' – pjgranahan

0

Desde dentro de mi archivo .erb, que tenía que hacer esto:

<%= ERB.new(File.read('pathToFile/myFile.erb'), nil, nil, '_sub01').result(binding) %> 

Las otras respuestas en este tema asumido que tenía una variable con su contenido en ella. Esta versión recupera el contenido.

Cuestiones relacionadas