Есть ли безопасный метод усечения HTML в Rails? - PullRequest
41 голосов
/ 01 декабря 2010

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

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

Ответы [ 10 ]

80 голосов
/ 19 февраля 2014

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

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

RubyOnRails.org

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

35 голосов
/ 31 августа 2011

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

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

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

Допустим, у вас работает гем HTML-анализатора и вы нашли наименьшее количество общих знаменателейэто будет работать большую часть времени.

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

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

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

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

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

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, сколько считаете нужным.Я использовал их, но px так же хорош.

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

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

6 голосов
/ 25 марта 2011

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

3 голосов
/ 25 августа 2015

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

raw your_string.truncate(200)
2 голосов
/ 29 ноября 2012

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

1 голос
/ 09 июля 2019
your_tagged_string.truncate(60).html_safe
1 голос
/ 12 июня 2013

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

truncate(html.gsub(/(<[^>]+>)/, ''), 5)
0 голосов
/ 13 июня 2016

Мы можем сделать это с помощью simple_format http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format

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

=> "123 456 7890"

0 голосов
/ 04 июля 2013

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

view :

<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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...