2010-10-14 4 views
44

rails 3 semble échapper à tout, y compris html. J'ai essayé d'utiliser raw() mais il échappe toujours à html. Y at-il un travail autour? Ceci est mon aide que j'utilise (/helpers/application_helper.rb):Ne pas échapper html en rubis sur rails

module ApplicationHelper 
    def good_time(status = true) 
    res = "" 
    if status == true 
     res << "Status is true, with a long message attached..." 
    else 
     res << "Status is false, with another long message" 
    end 
    end 
end 

J'appelle l'aide à mon avis en utilisant ce code:

<%= raw(good_time(true)) %> 

Répondre

80

Vous pouvez utiliser .html_safe comme ceci:

def good_time(status = true) 
    if status 
    "Status is true, with a long message attached...".html_safe 
    else 
    "Status is false, with another long message".html_safe 
    end 
end 

<%= good_time(true) %> 
+1

Merci! J'ai trouvé un moyen de le réparer juste après avoir posté la question, mais c'est beaucoup plus élégant et simpliste. – alexy13

+10

Réponse exceptionnelle. Malgré les tutoriels de 15 minutes, il m'étonne toujours de voir à quel point certaines des tâches les plus triviales sont difficiles dans Rails. Avoir un bulldozer est très bien, mais il y a des fois où vous avez besoin d'une fourchette de crevettes. :) –

3

je suis tombé sur cette même chose et a découvert une solution plus sûre que l'utilisation html_safe, en particulier une fois que vous introduisez des chaînes qui sont dynamiques.

D'abord, le code mis à jour:

def good_time(long_message1, long_message2, status = true) 
    html = "".html_safe 
    html << "Status is #{status}, " 
    if status 
    html << long_message1 
    else 
    html << long_message2 
    end 
    html 
end 

<%= good_time(true) %> 

Ce échappe long_message contenu si elle est dangereuse, mais laisse unescape s'il est sûr.

Ceci permet "long message for success & such." d'afficher correctement, mais aussi échappe "malicious message <script>alert('foo')</script>".

L'explication se résume à ceci - 'foo'.html_safe retourne un ActiveSupport :: SafeBuffer qui agit comme une chaîne dans tous les sens, sauf un: Lorsque vous ajoutez une chaîne à un SafeBuffer (en appelant + ou < <), que d'autres cordes HTML est échappé avant d'être ajouté au SafeBuffer. Lorsque vous ajoutez un autre SafeBuffer à un SafeBuffer, aucun échappement ne se produira. Rails rend toutes vos vues sous le capot en utilisant SafeBuffers, donc la méthode mise à jour ci-dessus finit par fournir à Rails un SafeBuffer que nous avons contrôlé pour effectuer l'échappement sur le long_message "selon les besoins" plutôt que "toujours". Maintenant, le crédit pour cette réponse va entièrement à Henning Koch, et est expliqué de manière beaucoup plus détaillée au Everything you know about html_safe is wrong - mon récapitulatif ci-dessus tente seulement de fournir l'essence de l'explication dans le cas où ce lien meurt jamais.

+0

Cela n'a pas beaucoup de sens, car il va échapper * tout * HTML dans 'long_message1' et' long_message2'. Le demandeur semble vouloir autoriser du HTML. Il peut le faire en appelant '.html_safe' sur la chaîne, mais évidemment il ne devrait le faire que s'il peut faire confiance à la chaîne. Ce que vous suggérez ne permettra pas de HTML, tout va être échappé. Corrigez-moi si j'ai tort, s'il-vous plait. – Mischa

+0

@Mischa Cela n'échappe pas à tout le HTML dans 'long_message1' et' long_message2' - c'est tout le point. :-) Le comportement de concaténation de SafeBuffer n'échappe au contenu que s'il est dangereux. Dans ma réponse, j'inclus un exemple avec '&', qui est correctement * not * échappé, et affiche comme '&' (pas '&'). Aussi, si vous êtes curieux pour plus d'exemples et de détails, notez le lien vers l'explication complète de Henning Koch. – DreadPirateShawn

+0

Merci. Je suppose que je dois regarder de plus près à SafeBuffer. Je me demande comment cela détermine ce qui est sûr et ce qui ne l'est pas. Par exemple, si Asker veut avoir un lien dans son message? Cela permettrait-il cela dans votre mise en œuvre? – Mischa