Nota: No estoy usando rieles, sinatra o inclinación, solo el ERB incorporado de Ruby.
Supongamos que tengo dos archivos erb:
archivo1.erb:
Start <%= yield if block_given? -%> Endy archivo2.erb:
<% render('file1.erb') do %> Some text <% end %>Me gustaría obtener una salida que se vea así:
Start Some text EndSin embargo, con el siguiente código ruby:
require 'erb' def render(file) content = File.read(file) b = binding ERB.new(content, trim_mode: '-').result b end res = render('file2.erb') Solo recibo "Algo de texto". Y si cambio la primera línea de file2.erb para usar <%= en lugar de <% , aparece un error de sintaxis:
Traceback (most recent call last): 3: from test.rb:9:in `<main>' 2: from test.rb:6:in `render' 1: from /usr/lib/ruby/2.7.0/erb.rb:905:in `result' /usr/lib/ruby/2.7.0/erb.rb:905:in `eval': (erb):1: syntax error, unexpected ')' (SyntaxError) ...t.<<(( render('file1.erb') do ).to_s); _erbout.<< "\\n Some T... ... ^ (erb):3: syntax error, unexpected `end', expecting ')' ; end ; _erbout.<< "\\n".freeze ^~~ (erb):4: syntax error, unexpected end-of-input, expecting ')'¿Hay alguna forma de hacer que esto funcione con el módulo 'erb'?
Puedo hacer que el rendimiento funcione si uso un bloque que devuelve una expresión directamente, pero eso no funcionará en mi caso.
Otra respuesta tiene una solución en la que el código de llamada puede representar una plantilla dentro de un diseño diferente. Pero eso realmente no funciona para mí, porque necesito definir el diseño para usar dentro de la plantilla (no hay realmente un equivalente de un controlador en mi código).
Pensé en hacer algo como cambiar .result a .run y ejecutarlo así:
$stdout = outstream render('file2.erb')Pero por alguna razón los resultados en la salida:
Start Some Text End Some TextTenga en cuenta el "Algo de texto" adicional al final.
Como ya señaló, dado que no estamos generando el valor de retorno del método de render con <%= , en el primer caso solo obtenemos Some text en la salida, el resto solo se usa en el procesamiento.
En segundo lugar, cuando usó run con plantilla, lo que hace que el result se ejecute dos veces, la primera vez para la template que se llama en el primer archivo de script y luego la segunda vez para la template que se llama dentro file2.erb render .
Para resolver el problema, puede capturar la salida en una variable y luego imprimir la salida de la variable capturada como se muestra a continuación:
archivo2.erb
<% @result = render('file1.erb') do -%> <% "Some text\n" -%> <% end -%> <%= @result -%>Producción
Start Some Text End Nota: puede usar HEREDOC para colocar una gran cantidad de texto entre <% -%>
<% @result = render('file1.erb') do -%> <% <<~EOF Some Text EOF -%> <% end -%> <%= @result -%>