Rails 中是否有 HTML 安全的截断方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4320160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there an HTML safe truncate method in Rails?
提问by Jesse Hattabaugh
I have a string of HTML in Rails. I'd like to truncate the string after a certain number of characters not including the HTML markup. Also, if the split happens to fall in the middle of an opening and closing tag, I'd like to close the open tag/s. For example;
我在 Rails 中有一个 HTML 字符串。我想在一定数量的字符后截断字符串,不包括 HTML 标记。另外,如果拆分恰好落在开始和结束标记的中间,我想关闭打开标记/秒。例如;
html = "123<a href='#'>456</a>7890"
truncate_markup(html, :length => 5) --> "123<a href='#'>45</a>"
采纳答案by gdelfino
There are two completely different solutions both with the same name: truncate_html
有两种完全不同的解决方案,它们都具有相同的名称: truncate_html
- https://github.com/ianwhite/truncate_html: This is a gem and uses an html parser (nokogiri)
- https://github.com/hgmnz/truncate_html: This is a file you put in your helpers directory. It uses regular expressions and has no dependencies.
- https://github.com/ianwhite/truncate_html:这是一个 gem 并使用 html 解析器(nokogiri)
- https://github.com/hgmnz/truncate_html:这是您放在 helpers 目录中的文件。它使用正则表达式并且没有依赖项。
回答by msanteler
the regular truncate
function works fine, just pass :escape => false
as an option to keep the HTML intact. eg:
常规truncate
功能工作正常,只需:escape => false
作为选项传递以保持 HTML 完整。例如:
truncate(@html_text, :length => 230, :omission => "" , :escape => false)
*EditI didn't read the question very carefully (or at all TBH), so this answer does not solve this question... It IS the answer I happened to be looking for though, so hopefully it helps 1 or 2 people :)
*编辑我没有很仔细地阅读这个问题(或者根本没有仔细阅读),所以这个答案并没有解决这个问题......但这是我碰巧正在寻找的答案,所以希望它可以帮助 1 或 2 人: )
回答by mastaBlasta
You should solve this problem with CSS rather than Ruby. You are doing something that affects the DOM layout, and there is no way to programmatically devise a solution that will work consistently.
您应该使用 CSS 而不是 Ruby 来解决这个问题。您正在做一些会影响 DOM 布局的事情,并且无法以编程方式设计出一致工作的解决方案。
Let's say you get your HTML parser gem working, and you find a lowest common denominator character count that will work most of the time.
假设您让 HTML 解析器 gem 正常工作,并且您找到了一个在大多数情况下都可以工作的最低公分母字符数。
What happens if you change font sizes, or your site layout? You'll have to recalculate the character count again.
如果更改字体大小或站点布局会怎样?您将不得不再次重新计算字符数。
Or let's say your html has something like this in it: <p><br /></p><br />
That is zero characters, however it would cause a big chunk of blank text to be inserted. It could even be a <blockquote>
or <code>
tag with too much padding or margin to throw your layout totally out of whack.
或者假设您的 html 中有这样的内容:<p><br /></p><br />
那是零个字符,但是它会导致插入一大块空白文本。它甚至可能是带有过多填充或边距的<blockquote>
or<code>
标签,使您的布局完全失控。
Or the inverse, let's say you have this 3 ≅ λ
(3 ≅ λ) That is 26 characters long, but for display purposes it is only 5.
或者相反,假设您有这个3 ≅ λ
(3 ≅ λ),即 26 个字符长,但出于显示目的,它只有 5 个。
The point being that character count tells you nothing about how something will render in the browser. Not to mention the fact HTML parsers are hefty pieces of code that can at times be unreliable.
关键是字符数不会告诉您某些内容将如何在浏览器中呈现。更不用说 HTML 解析器是大量有时不可靠的代码。
Here is some good CSS to deal with this. The :after pseudo class will add a white fade to the last line of content. Very nice transition.
这里有一些很好的 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
}
You can add as many .lines-x
classes as you see fit. I used em but px is just as good.
您可以根据需要添加任意数量的.lines-x
类。我用过 em 但 px 也一样好。
Then apply this to your element: <div class="truncate lines-3">....lots of stuff.. </div>
然后将其应用于您的元素: <div class="truncate lines-3">....lots of stuff.. </div>
and the fiddle: http://jsfiddle.net/ke87h/
和小提琴:http: //jsfiddle.net/ke87h/
回答by Mark
You could use the truncate_htmlplugin for this. It uses nokogiriand htmlentitiesgems and does exactly what the plugin name suggests.
您可以为此使用truncate_html插件。它使用nokogiri和htmlentitiesgems,并且完全按照插件名称的要求执行。
回答by jmanrubia
We had this need in zendone.com. The problem was that the existing solutions were very slow when truncating long HTML documents (MBs) into shorter ones (KBs). I ended up coding a library based in Nokogiri called truncato. The library includes some benchmarkscomparing its performance with other libs.
我们在 zendone.com 上有这个需求。问题是现有解决方案在将长 HTML 文档 (MB) 截断为较短的 (KB) 时速度非常慢。我最终编写了一个基于 Nokogiri 的名为truncato的库。该库包括一些基准测试,将其性能与其他库进行比较。
回答by Asnad Atta
This will help you without any extra effort
这将帮助您无需任何额外的努力
raw your_string.truncate(200)
回答by priyanka Ukirde
You can use
您可以使用
truncate(html.gsub(/(<[^>]+>)/, ''), 5)
回答by Marcos R. Guevara
your_tagged_string.truncate(60).html_safe
回答by Vijay Chouhan
We can do that with the help of simple_format http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
我们可以在 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 4567890"
=> "123 4567890"
回答by Maximus S
Solving this problem from the client side:
从客户端解决这个问题:
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
css
.preview-small {
height: 100px;
overflow: hidden;
}
.preview-large {
height: 200px;
overflow: hidden;
}