2012-01-26 3 views
1

У меня есть база данных, заполненная старыми сообщениями в блоге, которые я пытаюсь перейти на Rails. Поле тела состоит из сообщений, которые выглядят имеют формат, похожий на этот:Рендеринг безопасного html в Rails 3

Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. 

<iframe src="http://www.youtube.com?v=XXXXXXXX" width="400" height="250"></iframe> 

Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. 

<ul> 
<li>List item</li> 
<li>List item</li> 
<li>List item</li> 
<li>List item</li> 
</ul> 

Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. Paragraph text paragraph text paragraph text and even more paragraph text. 

Так что я пытаюсь сделать, это обернуть текст пункта в <p>, но оставить другие HTML элементы в одиночку. Вот что я пытался:

simple_format (@ post.body) = это ставит <p> вокруг все, но и загрязняет мои неупорядоченные списки с перерывами между каждым элементом списка. Кроме того, вставка iframe не будет отображаться.

сырье (@ post.body) или @ post.body.html_safe = Функция Iframe код вставки и маркированные списки показать большой, но все работает вместе, так как нет никакой замены для новых линий.

simple_format (@ post.body, {}, {: sanitize => false}) = Прохладный. Теперь я вижу все html-теги! Не работает на всех

@ post.body.gsub (/ \ г \ п? /, "<br/>") .html_safe = Та же проблема, как с simple_format ... Я получаю разрывы строк в моем Теги элемента html block.

Любые предложения о том, как это сделать?

+0

Внимание! Вызов 'html_safe' на unsanitized, untrusted strings * будет * оставить вас открытым для атак XSS. Если вы вызываете 'html_safe' на что-то, вы должны быть абсолютно уверены *, что эта строка не будет содержать ненадежный ввод пользователя. – Ajedi32

ответ

2

Я думаю, что вы чуть было его в последнем примере, но я думаю, что вам нужно сделать .html_safe раньше:

@post.body.html_safe.gsub(/\r\n?/,"<br/>") 
+0

Не совсем. Gsub возвращает его обратно в строку со всем html, видимым на рендере. – bjork24

+1

С первого взгляда, я думаю, что это снова должно быть 'html_safe'-ed. Попробуйте '@ post.body.html_safe.gsub (/ \ r \ n? /,"
") .html_safe'. По умолчанию gsub будет дезинфицированной строкой. –

1

Я думаю, что ваш вопрос имеет меньше делать с рельсами, чем пытаться исправить сломанный html. В любом случае ваш пример подсказывает, что текст, который должен быть обернут в теги <p>, это строки, которые еще не начинаются с тега. Только вы знаете, относится ли это правило к другим сообщениям.

Попробуйте это. Он также учитывает ведущие пробелы.

raw(@post.body.gsub(/^\s*[^<].*/, '<p>\&</p>')) 

Если вышеизложенное слишком хрупкое, я предлагаю использовать Nokogiri. Это происходит каждый верхнего уровень непрерывного блок текста и заворачивает его в <p>:

doc = Nokogiri.XML("<body>\n" + @post.body + "\n</body>\n") 
doc.root.children.each{|c| c.text? and c.replace("<p>#{c.to_s.strip}</p>") } 
raw(doc.root.inner_html) 

Для вставки <br> сек на переносах в текстовых блоках, вы можете заменить c.to_s.strip выше c.to_s.strip.gsub(/\r?\n/, "<br/>\n").

Я заметил, что ваш вопрос был /\r\n?/. Вы когда-нибудь ожидали возвращения старой каретки Mac OS (\r)? Если вы хотите работать с Windows или Unix, вы должны использовать /\r?\n/.

1

Я думаю sanitize может быть, что вы хотите

%= sanitize @article.body %> 


def sanitize(html, options = {}) 
    self.class.white_list_sanitizer.sanitize(html, options).try(:html_safe) 
end 
Смежные вопросы