Ruby on Rails: como renderizar uma string como HTML?

154

eu tenho

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

e na minha visão erb:

<%= @str %>

O que será exibido na página é: <b>Hi</b>quando o que realmente quero é oi . Qual é a maneira ruby ​​de "interpretar" uma string como marcação HTML?


Edit : o caso em que

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

Se, na minha opinião, eu faço

<%raw @str %>

O código-fonte HTML é <span class=\"classname\">hello</spanonde está o que realmente quero <span class="classname">hello</span>(sem as barras invertidas que estavam escapando das aspas duplas). Qual é a melhor maneira de "retirar" essas aspas duplas?

Tim
fonte
Você também pode considerar o uso da sintaxe% Q [] para escape de string. por exemplo, %Q["quotation marks"] => "\"quotation marks\"" Fonte: en.wikibooks.org/wiki/Ruby_Programming/Syntax/… Não sei se isso ajuda.
0112:

Respostas:

328

ATUALIZAR

Por motivos de segurança, é recomendável usar em sanitizevez de html_safe. Ligação


O que está acontecendo é que, como medida de segurança, o Rails está escapando da sua string para você, pois pode ter um código malicioso incorporado. Mas se você disser ao Rails que sua string é html_safe, ela passará direto.

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

OU

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

Usar rawfunciona bem, mas tudo o que está fazendo é converter a string em uma string e chamar html_safe. Quando sei que tenho uma string, prefiro chamar html_safe diretamente, porque pula uma etapa desnecessária e torna mais claro o que está acontecendo. Detalhes sobre escape de cadeia e proteção XSS estão neste Asciicast .

Jacob
fonte
Fantástico. Não consegui descobrir como fazer isso, mesmo depois de pesquisar por uma hora. Obrigado pela sua resposta.
Salil
1
Eu sempre usei raw. Muito feliz em saber sobre isso!
precisa saber é o seguinte
Dando torcidas do futuro =)
Carlos Morales
1
de desinfecção é removido de acordo com stackoverflow.com/questions/44575106/...
Youness
16

Use cru :

<%=raw @str >

Mas como @ jmort253 diz corretamente, considere onde o HTML realmente pertence.

Michael Stum
fonte
Olá, esta solução funciona, exceto com uma ressalva: consulte a pergunta editada
Tim
14

Se você railsusa Erubis - a maneira mais legal de fazer isso é

<%== @str >

Observe o sinal de igual duplo. Consulte a pergunta relacionada no SO para obter mais informações.

jibiel
fonte
7

Você está misturando sua lógica de negócios com seu conteúdo. Em vez disso, recomendo enviar os dados para sua página e, em seguida, usar algo como JQuery para colocar os dados onde você precisa.

Isso tem a vantagem de manter todo o seu HTML nas páginas HTML onde ele pertence, para que seus web designers possam modificá-lo posteriormente sem precisar passar pelo código do servidor.

Ou, se você não quiser usar JavaScript, tente o seguinte:

@str = "Hi"

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

Pelo menos dessa maneira, seu HTML está na página HTML a que pertence.

jmort253
fonte
O problema é que meu aplicativo está capturando um arquivo mal marcado e "traduzindo" por meio de expressões regulares para uma boa marcação HTML para enviar para a exibição. Portanto, a marcação HTML que está sendo gerada é dinâmica, portanto, não posso saber a priori quais tags devem envolver @str. Onde eu realizaria esse trabalho de "tradução", se não nos modelos? Eu pensei que não deveríamos ter extenso código lógico nas visualizações.
Tim
1
É realmente uma questão de opinião. Ao desenvolver um aplicativo novo, prefiro manter tudo o mais limpo possível. Mas muitas vezes precisamos trabalhar dentro das restrições do que os outros nos deixaram. Se sua fonte de dados retornar a marcação HTML, talvez seja necessário usar "raw", conforme descrito na solução de Michael Stum.
precisa saber é o seguinte
1
Se você herdou o suporte de algum código, e o código possui áreas que mostram um pensamento ou design inadequado, é realmente de sua responsabilidade limpá-lo para torná-lo mais sustentável. Deixá-lo como você descobriu é bom quando é um ótimo código, mas deixá-lo melhor do que você achou é bom quando precisava de trabalho. Parte do meu trabalho é gerenciar alguns aplicativos herdados; Sou fã de não consertar coisas que não estão quebradas, mas elas não podem ser aprimoradas facilmente por causa de como foram escritas. Eu tive que reescrever a maioria das chamadas de função, mas agora é muito mais fácil trabalhar com isso.
the Tin Man
Você não deve usar JavaScript para sua interpolação HTML se não houver outro motivo para usar JS. Isso vai quebrar o seu site para navegadores não-JS (sim, há são alguns).
Marnen Laibow-Koser
1
Obviamente, se você permitir que o conteúdo não escapado resposabitily de garantir a marcação não má é com você.
Macario
6

Ou você pode tentar o método CGI.unescapeHTML .

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

desde que você está traduzindo e escolhendo o código desejado do arquivo codificado de baixa qualidade de uma pessoa, você pode usar content_tag, em combinação com o seu regex.

Roubando os documentos da API, você pode interpolar esse código traduzido para algo content_tagcomo:

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

Sem conhecer seu código, esse tipo de pensamento garantirá que o código traduzido seja muito compatível.

pjammer
fonte
Estou assumindo que o texto traduzido é o conteúdo real dentro da div, certo? ou seja, no exemplo, seria "Olá, mundo!"? E se o translate_text tiver mais HTML, ou seja, divs ou extensões aninhadas? Eu precisaria chamar content_tag várias vezes?
Tim
e ... desculpe, pressione enter mais cedo ... cada div / span aninhado ainda é uma tag de conteúdo e você ainda precisa validá-la, certo? Como não podemos ver o que você está fazendo com sua tradução sofisticada ;-), eu suponho que você procure TODAS as tags, independentemente de o regex estar no 'pai' do html ... como <ul>. você não colocaria todos os li's como uma grande bunda para imprimir, não é? cada um seria seu próprio content_tag: li, texto correto?
pjammer
0

@str = "<span class=\"classname\">hello</span>" Se, na minha opinião, eu faço

<%raw @str %> O código-fonte HTML é <span class=\"classname\">hello</span>onde realmente quero <span class="classname">hello</span>(sem as barras invertidas que estavam escapando das aspas duplas). Qual é a melhor maneira de "retirar" essas aspas duplas?

Solução: use aspas duplas dentro de aspas simples (ou simples dentro de aspas duplas) para evitar escapar com uma barra invertida.

@str = '<span class="classname">hello</span>'
<%raw @str %>
Batida
fonte
0

A versão html_safe funciona bem no Rails 4 ...

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