传说中的truncate_html

学习用rails做blog的时候要用到rails的truncate功能。

<%= h truncate(post.content, 100, "...") %>

问题来了,将html截断后出现不完整的tag,导致后续的文章排版都错乱了。
本来考虑是不是自己写一个,正在思考思路,结果祭起google,好吗,已经有牛人写了
原地址:[url]http://henrik.nyh.se/2008/01/rails-truncate-html-helper[/url]
简单记录一下:
将下面代码保存到app/helpers/text_helper.rb。
# By Henrik Nyh <http://henrik.nyh.se> 2008-01-30.
# Free to modify and redistribute with credit.

require "rubygems"
require "hpricot"

module TextHelper

# Like the Rails _truncate_ helper but doesn't break HTML tags or entities.
def truncate_html(text, max_length = 30, ellipsis = "...")
return if text.nil?

doc = Hpricot(text.to_s)
ellipsis_length = Hpricot(ellipsis).inner_text.chars.length
content_length = doc.inner_text.chars.length
actual_length = max_length - ellipsis_length

content_length > max_length ? doc.truncate(actual_length).inner_html + ellipsis : text.to_s
end

end

module HpricotTruncator
module NodeWithChildren
def truncate(max_length)
return self if inner_text.chars.length <= max_length
truncated_node = self.dup
truncated_node.children = []
each_child do |node|
remaining_length = max_length - truncated_node.inner_text.chars.length
break if remaining_length == 0
truncated_node.children << node.truncate(remaining_length)
end
truncated_node
end
end

module TextNode
def truncate(max_length)
# We're using String#scan because Hpricot doesn't distinguish entities.
Hpricot::Text.new(content.scan(/&#?[^\W_]+;|./).first(max_length).join)
end
end

module IgnoredTag
def truncate(max_length)
self
end
end
end

Hpricot::Doc.send(:include, HpricotTruncator::NodeWithChildren)
Hpricot::Elem.send(:include, HpricotTruncator::NodeWithChildren)
Hpricot::Text.send(:include, HpricotTruncator::TextNode)
Hpricot::BogusETag.send(:include, HpricotTruncator::IgnoredTag)
Hpricot::Comment.send(:include, HpricotTruncator::IgnoredTag)

然后在app/controllers/application.rb中添加
  helper Text

现在可以在view代码中使用
<%= h truncate_html(post.content, 100, "...") %>

ok,完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值