开发者

Rails 3 and html_safe confusion (allow pictures (smiles) in chat but deny everything else)

I have here is a module that replaces the smilies (like ":-)") as icons:

module Smileize
  PATH = "/images/smiles"
  SMILES = [/\;\-?p/i, /\$\-?\)/, /8\-?\)/, /\>\:\-?\(/, /\:\-?\*/, /\:\-?o/i, /\:\-?c/i, /\;\-?\)/, 
/\:\-?s/i, /\:\-?\|/, /\:\-?p/i, /\:\-?D/i, /\:\-?\?/, /\:\-?\(/, /\:\-?\)/]
  def to_icon(key)
    return "<img class='smiley' src='#{PATH}/smile#{SMILES.index(key) + 1}.png'/>"
  end
  module_function :to_icon
end

class String
  def to_smile
    Smileize::SMILE开发者_如何学PythonS.each do |smile|
      if self =~ smile
        self.gsub!(smile, Smileize.to_icon(smile))
      end
    end
    self
  end
end

So pictures show that I'm using html_safe, like this:

<%= @message.text.to_smile.html_safe %>

But it does not suit me, because but pictures will be displayed and other tags, too.

My question is: how to display only my smile, ignoring the other tags?


I think you'll need to do it like this:

  1. HTML encode the string.
  2. Perform your substitution.
  3. Mark the final result as HTML safe.

Add a helper something like this:

def expand_smilies(s)
  s = ERB::Util::html_escape(s)
  Smileize::SMILES.each do |smile|
    s.gsub!(smile, Smileize.to_icon(smile))
  end
  s.html_safe
end

And then in your ERB:

<%= expand_smilies some_text %>

ERB uses ERB::Util::html_escape to encode HTML so using it yourself makes sense if you're targeting ERB. Calling html_safe on a string returns you something that ERB will leave alone when it is HTML encoding things.

Note that there is no usable html_safe! on strings and html_safe returns an ActiveSupport::SafeBuffer rather than a String so you'll have to use a helper rather than monkey patching a new method into String. ActiveSupport does patch an html_safe! method into String but all it does is raise an exception saying "don't do that":

def html_safe!
  raise "You can't call html_safe! on a String"
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜