Ruby on Rails: ¿cómo representar una cadena como HTML?

154

yo tengo

@str = "<b>Hi</b>"

y en mi opinión erb:

<%= @str %>

Lo que se mostrará en la página es: <b>Hi</b>cuando lo que realmente quiero es Hola . ¿Cuál es la forma rubí de "interpretar" una cadena como marcado HTML?


Editar : el caso donde

@str = "<span class=\"classname\">hello</span>"

Si en mi opinión lo hago

<%raw @str %>

El código fuente HTML es <span class=\"classname\">hello</span> donde lo que realmente quiero es <span class="classname">hello</span>(sin las barras invertidas que se escapaban de las comillas dobles). ¿Cuál es la mejor manera de "escapar" de esas comillas dobles?

Tim
fuente
También puede considerar usar la sintaxis% Q [] para el escape de cadena. por ejemplo, %Q["quotation marks"] => "\"quotation marks\"" Fuente: en.wikibooks.org/wiki/Ruby_Programming/Syntax/… No sé si eso ayuda.
0112

Respuestas:

328

ACTUALIZAR

Por razones de seguridad, se recomienda usar en sanitizelugar de html_safe. Enlace


Lo que sucede es que, como medida de seguridad, Rails está escapando de su cadena porque podría tener código malicioso incrustado en ella. Pero si le dice a Rails que su cadena es html_safe, la pasará de inmediato.

@str = "<b>Hi</b>".html_safe
<%= @str %>

O

@str = "<b>Hi</b>"
<%= @str.html_safe %>

Usar rawfunciona bien, pero todo lo que hace es convertir la cadena en una cadena y luego llamar a html_safe. Cuando sé que tengo una cadena, prefiero llamar a html_safe directamente, porque omite un paso innecesario y deja en claro lo que está sucediendo. Los detalles sobre el escape de cadenas y la protección XSS se encuentran en este Asciicast .

Jacob
fuente
Fantástico. No pude encontrar cómo hacerlo incluso después de buscar durante una hora. Gracias por tu respuesta.
Salil
1
Siempre he usado raw. Muy contento de saber sobre esto!
jmcharnes
Dando madejas del futuro =)
Carlos Morales
1
desinfección se elimina de acuerdo con stackoverflow.com/questions/44575106/…
Youness
16

Use crudo :

<%=raw @str >

Pero como dice correctamente @ jmort253, considere dónde pertenece realmente el HTML.

Michael Stum
fuente
Hola, esta solución funciona, excepto con una advertencia: vea la pregunta editada
Tim
14

Si railsutiliza Erubis , la mejor manera de hacerlo es

<%== @str >

Tenga en cuenta el doble signo igual. Consulte la pregunta relacionada sobre SO para obtener más información.

jibiel
fuente
7

Estás mezclando tu lógica de negocios con tu contenido. En cambio, recomendaría enviar los datos a su página y luego usar algo como JQuery para colocar los datos donde los necesite.

Esto tiene la ventaja de mantener todo su HTML en las páginas HTML a las que pertenece para que sus diseñadores web puedan modificar el HTML más tarde sin tener que pasar por el código del lado del servidor.

O si no quieres usar JavaScript, puedes probar esto:

@str = "Hi"

<b><%= @str ></b>

Al menos de esta manera, su HTML está en la página HTML a la que pertenece.

jmort253
fuente
El problema es que mi aplicación está tomando un archivo que está mal marcado y lo "traduce" a través de expresiones regulares a un buen marcado HTML para enviar a la vista. Por lo tanto, el marcado HTML que se está generando es dinámico, por lo que no puedo saber a priori qué etiquetas se supone que rodean a @str. ¿Dónde realizaría este trabajo de "traducción", si no fuera en los modelos? Pensé que no debíamos tener un código lógico extenso en las vistas.
Tim
1
Es realmente una cuestión de opinión. Al desarrollar una aplicación nueva, prefiero mantener todo lo más limpio posible. Pero a menudo debemos trabajar dentro de las limitaciones de lo que otros nos han dejado. Si su fuente de datos devuelve el marcado HTML, entonces quizás eche un vistazo al uso de "raw" como se describe en la solución de Michael Stum.
jmort253
1
Si ha heredado el soporte de algún código, y el código tiene áreas que muestran un pensamiento o un diseño deficientes, entonces es realmente su responsabilidad limpiarlo para que sea más fácil de mantener. Dejarlo como lo encontró está bien cuando es un gran código para empezar, pero dejarlo mejor de lo que encontró es bueno cuando necesita trabajo. Parte de mi trabajo es administrar algunas aplicaciones heredadas; Soy fanático de no arreglar cosas que no están rotas, pero que no podrían mejorarse fácilmente debido a cómo fueron escritas. Tuve que reescribir la mayoría de las llamadas a funciones, pero ahora es mucho más fácil trabajar con ellas.
The Tin Man el
No debería usar JavaScript para su interpolación HTML si no hay otra razón para usar JS. Eso va a romper su sitio para los navegadores no-JS (sí, no son algunos).
Marnen Laibow-Koser
1
Por supuesto, si permite contenido no escapado, la responsabilidad de garantizar un marcado no malo depende de usted.
Macario
6

O puede probar el método CGI.unescapeHTML .

CGI.unescapeHTML "&lt;p&gt;This is a Paragraph.&lt;/p&gt;"
=> "<p>This is a Paragraph.</p>"
Arman Ortega
fuente
0

ya que está traduciendo y seleccionando su código deseado del archivo codificado de una persona, ¿podría usar content_tag, en combinación con sus expresiones regulares?

Al robar los documentos de la API, puede interpolar este código traducido en un me content_taggusta:

<%= content_tag translated_tag_type.to_sym, :class => "#{translated_class}" do -%>
<%= translated_text %>
<% end -%>
# => <div class="strong">Hello world!</div>

Sin conocer su código, este tipo de pensamiento se asegurará de que su código traducido sea demasiado compatible.

pjammer
fuente
Supongo que traducir_text es el contenido real dentro del div, ¿verdad? es decir, en el ejemplo, sería "¡Hola mundo!" ¿Qué sucede si el texto_traducido tiene más HTML, es decir, div o espacios anidados? ¿Tendría que llamar a content_tag muchas veces entonces?
Tim
y ... perdón, presione enter temprano ... cada división / intervalo anidado en el interior sigue siendo una etiqueta de contenido y aún debe validarlo, ¿verdad? Como no podemos ver lo que está haciendo con su traducción elegante ;-), supongo que busca TODAS las etiquetas, independientemente de si la expresión regular está en el 'padre' del html ... como <ul>. no pondrías todos los li's como una gran cuerda para imprimir, ¿verdad? cada uno sería su propio content_tag: li, texto correcto?
pjammer
0

@str = "<span class=\"classname\">hello</span>" Si en mi opinión lo hago

<%raw @str %> El código fuente HTML es <span class=\"classname\">hello</span>donde realmente quiero <span class="classname">hello</span>(sin las barras invertidas que escapaban a las comillas dobles). ¿Cuál es la mejor manera de "escapar" de esas comillas dobles?

Solución: use comillas dobles dentro de comillas simples (o simples dentro de dobles) para evitar escapar con una barra diagonal inversa.

@str = '<span class="classname">hello</span>'
<%raw @str %>
Choque
fuente
0

La versión html_safe funciona bien en Rails 4 ...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
Georgia
fuente