Подтвердить что ты не робот

В Rails существует безопасный метод усечения HTML?

У меня есть строка HTML в Rails. Я хотел бы усечь строку после определенного количества символов, не считая разметки HTML. Кроме того, если разделение происходит в середине закрывающего и закрывающего тегов, я хотел бы закрыть открытый тег/с. Например:

html = "123<a href='#'>456</a>7890"
truncate_markup(html, :length => 5) --> "123<a href='#'>45</a>"
4b9b3361

Ответ 1

Существуют два совершенно разных решения с одинаковым именем: truncate_html

  • https://github.com/ianwhite/truncate_html: Это драгоценный камень и использует html-парсер (nokogiri)
  • https://github.com/hgmnz/truncate_html: это файл, который вы помещаете в каталог ваших помощников. Он использует регулярные выражения и не имеет зависимостей.

Ответ 2

регулярная функция truncate работает отлично, просто передайте :escape => false в качестве опции, чтобы сохранить HTML неповрежденным. например:

truncate(@html_text, :length => 230, :omission => "" , :escape => false)

RubyOnRails.org

* Редактировать Я не очень внимательно прочитал вопрос (или вообще TBH), поэтому этот ответ не решает этот вопрос... Это тот ответ, который я искал, хотя, так что, надеюсь, это поможет 1 или 2 людям:)

Ответ 3

Вы должны решить эту проблему с помощью CSS, а не с Ruby. Вы делаете что-то, что влияет на макет DOM, и нет никакого способа программно разработать решение, которое будет работать последовательно.

Предположим, что вы используете свой обработчик парсера HTML, и вы найдете самый низкий общий символ знаменателя, который будет работать большую часть времени.

Что произойдет, если вы измените размер шрифта или ваш макет сайта? Вам придется пересчитать количество символов снова.

Или скажем, что у вашего html есть что-то в этом роде: <p><br /></p><br /> Это нулевые символы, однако это приведет к добавлению большого фрагмента пустого текста. Это может быть даже тег <blockquote> или <code> со слишком большим количеством отступов или полей, чтобы полностью отбросить ваш макет.

Или обратный, скажем, у вас есть этот 3&nbsp;&#8773;&nbsp;&#955; (3 ≅ λ) длиной 26 символов, но для целей отображения это всего 5.

Дело в том, что количество символов ничего не говорит о том, как что-то будет отображаться в браузере. Не говоря уже о том, что синтаксические анализаторы HTML представляют собой множество фрагментов кода, которые иногда могут быть ненадежными.

Вот хороший CSS, чтобы справиться с этим. Класс: после псевдо класса добавит белое затухание к последней строке содержимого. Очень приятный переход.

body { font-size: 16px;}
p {font-size: 1em; line-height: 1.2em}
/* Maximum height math is:
   line-height * #oflines - 0.4
   the 0.4 offset is to make the cutoff  look nicer */
.lines-3{height: 3.2em;}
.lines-6{height: 6.8em;}
.truncate {overflow: hidden; position:relative}
.truncate:after{
    content:""; 
    height: 1em; 
    display: block; 
    width: 100%; 
    position:absolute;
    background-color:white; 
    opacity: 0.8; 
    bottom: -0.3em
}

Вы можете добавить столько классов .lines-x, сколько сочтете нужным. Я использовал em, но px так же хорош.

Затем примените это к вашему элементу: <div class="truncate lines-3">....lots of stuff.. </div>

и скрипт: http://jsfiddle.net/ke87h/

Ответ 4

Для этого можно использовать плагин truncate_html. Он использует nokogiri и htmlentities gems и делает именно то, что предлагает название плагина.

Ответ 5

Это поможет вам без лишних усилий.

raw your_string.truncate(200)

Ответ 6

У нас была эта потребность в zendone.com. Проблема заключалась в том, что существующие решения были очень медленными при сокращении длинных HTML-документов (МБ) до более коротких (КБ). Я закончил кодирование библиотеки в Nokogiri под названием truncato. В библиотеке несколько тестов сравниваются с другими библиотеками.

Ответ 7

Вы можете использовать

truncate(html.gsub(/(<[^>]+>)/, ''), 5)

Ответ 9

your_tagged_string.truncate(60).html_safe

Ответ 10

Решение этой проблемы с клиентской стороны:

вид

<script>
  $(function() {
    $('.post-preview').each(function() {
      var tmp_height = $(this).innerHeight();
      if ((tmp_height > 100) && (tmp_height < 200)) {
        $(this).addClass("preview-small");
      }
      else if (tmp_height >= 200) {
        $(this).addClass("preview-large")
      }
      else {
        //do nothing
      }
    });
  });
</script>

CSS

.preview-small {
  height: 100px;
  overflow: hidden;
}

.preview-large {
  height: 200px;
  overflow: hidden;
}