Rails 3 и html_safe путаница (разрешать картинки (улыбки) в чате, но запрещать все остальное) - PullRequest
1 голос
/ 28 июня 2011

У меня здесь есть модуль, который заменяет смайлики (например, ":-)") на иконки:

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::SMILES.each do |smile|
      if self =~ smile
        self.gsub!(smile, Smileize.to_icon(smile))
      end
    end
    self
  end
end

Итак, фотографии показывают, что я использую html_safe, вот так:

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

Но меня это не устраивает, потому что будут отображаться картинки и другие теги тоже.

Мой вопрос : как отобразить только мою улыбку, игнорируя другие теги?

1 Ответ

3 голосов
/ 28 июня 2011

Я думаю, вам нужно сделать это так:

  1. HTML кодирует строку.
  2. Выполните замену.
  3. Отметить конечный результат как безопасный HTML.

Добавьте помощника что-то вроде этого:

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

А потом в вашем ERB:

<%= expand_smilies some_text %>

ERB использует ERB::Util::html_escape для кодирования HTML, поэтому использование его самостоятельно имеет смысл, если вы нацеливаетесь на ERB. Вызов html_safe в строке возвращает вам что-то, что ERB оставит в покое, когда он кодирует HTML.

Обратите внимание, что в строках нет пригодных для использования html_safe! и html_safe возвращает ActiveSupport :: SafeBuffer вместо String, поэтому вам придется использовать скорее помощник чем обезьяна, исправляющая новый метод в String. ActiveSupport исправляет метод html_safe! в String, но все, что он делает, вызывает исключение, говорящее «не делай этого»:

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