質問

ニュース記事をリストするページがあります。ページの長さを減らすために、ティーザー (記事の最初の 200 単語 / 600 文字) のみを表示し、その後「詳細...」リンクを表示します。このリンクをクリックすると、残りの部分が展開されます。 jQuery/JavaScript の方法で記事を作成します。さて、すべてを理解し、貼り付けページで次のヘルパー メソッドを見つけました。これにより、ニュース記事 (文字列) が単語の途中で切り刻まれないようにすることができます。

 def shorten (string, count = 30)
    if string.length >= count
      shortened = string[0, count]
      splitted = shortened.split(/\s/)
      words = splitted.length
      splitted[0, words-1].join(" ") + ' ...'
    else
      string
    end
  end

私が抱えている問題は、DB から取得したニュース記事の本文が HTML 形式であることです。したがって、運が悪いと、上記のヘルパーは記事の文字列を HTML タグの真ん中で切り刻んで、そこに「more...」という文字列を挿入します (例:"" の間)、ページ上の HTML が破損します。

これを回避する方法はありますか、または HTML 文字列から抜粋/ティーザーを生成するために使用できるプラグインはありますか?

役に立ちましたか?

解決 3

のおかげであなたの答えのためにたくさん! しかし、その間に私は完全に自分の目的に合った jQueryのHTMLトランケータプラグインに、つまずいそして、クライアント側への切り捨てを移します。これは、任意の容易に取得していない: - )

他のヒント

次の組み合わせを使用できます。 消毒する そして 切り詰める.

truncate("And they found that many people were sleeping better.", 
  :omission => "... (continued)", :length => 15)
# => And they found... (continued)

私はブログ投稿があり、簡単な抜粋を表示したいだけの同様のタスクを実行しています。したがって、私の見解では、私は単に次のようにします。

sanitize(truncate(blog_post.body, length: 150))

これにより、HTML タグが取り除かれ、最初の 150 文字が得られ、ビューで処理されるため、MVC フレンドリーになります。

幸運を!

ここを

私の答えは、作業を行う必要があります。元の質問は(ERR、私が尋ねた)マークダウンを切り捨てについてだったが、それが動作するはずですので、私は、その切り捨てHTMLに値下げを変換してしまっています。

あなたのサイトは、多くのトラフィックを取得する場合、あなたは(ポストが作成/更新されたときに、おそらく、あなたがデータベースに抜粋を格納することができ?)の抜粋をキャッシュする必要があります。

もちろん、これはまた、ユーザーが変更する可能性を意味しますか自分の抜粋を入力してください。

使用方法:

>> puts "<p><b><a href=\"hi\">Something</a></p>".truncate_html(5, at_end = "...")
=> <p><b><a href="hi">Someth...</a></b></p>

..と(他の回答からコピーされた)コード:

require 'rexml/parsers/pullparser'

class String
  def truncate_html(len = 30, at_end = nil)
    p = REXML::Parsers::PullParser.new(self)
    tags = []
    new_len = len
    results = ''
    while p.has_next? && new_len > 0
      p_e = p.pull
      case p_e.event_type
      when :start_element
        tags.push p_e[0]
        results << "<#{tags.last}#{attrs_to_s(p_e[1])}>"
      when :end_element
        results << "</#{tags.pop}>"
      when :text
        results << p_e[0][0..new_len]
        new_len -= p_e[0].length
      else
        results << "<!-- #{p_e.inspect} -->"
      end
    end
    if at_end
      results << "..."
    end
    tags.reverse.each do |tag|
      results << "</#{tag}>"
    end
    results
  end

  private

  def attrs_to_s(attrs)
    if attrs.empty?
      ''
    else
      ' ' + attrs.to_a.map { |attr| %{#{attr[0]}="#{attr[1]}"} }.join(' ')
    end
  end
end

あなたがHTML要素の中央で分割したくない場合は、より複雑なパーサを記述する必要があります。それは、<>ブロックの途中で、そのの間に2つのタグ場合であれば覚えておく必要があります。

あなたがすることをしなかった場合でも、あなたはまだ問題があるでしょう。いくつかは、パーサーcouldntのが見つからないため、終了タグの、どこにでもそれを分割するので、html要素に記事全体を置けば。

それがすべてで可能である場合は、

私は記事の中に任意のタグを置くか、何も(なし<div>など)が含まれているいけないタグにそれを維持しないようにしようとするだろう。あなただけが非常に簡単ですタグの途中であるかどうかを確認する必要がありますそのようにます:

  def shorten (string, count = 30)
     if string.length >= count
       shortened = string[0, count]
       splitted = shortened.split(/\s/)
       words = splitted.length
       if(splitted[words-1].include? "<")
         splitted[0,words-2].join(" ") + ' ...'
       else
         splitted[0, words-1].join(" ") + ' ...'
     else
       string
     end   
  end

この消毒にHTMLで抽出した最初の刑に服している。と仮定して記モデルに、体属性が含まれるHTML:

# lib/core_ext/string.rb
class String
  def first_sentence
    self[/(\A[^.|!|?]+)/, 1]
  end
end

# app/models/article.rb
def teaser
  HTML::FullSanitizer.new.sanitize(body).first_sentence
end

このように変換す"<b>こと</b> が <em>重要</em> 。この条に"と"これは重要な条".

私は

この使用して、以下のソリューションを解決しました

宝石をインストールする 'サニタイズ'

gem install sanitize

、次のコードを使用し、ここではのボディのHTMLタグを含むテキストです。

<%= content_tag :div, Sanitize.clean(truncate(body, length: 200, separator: ' ', omission: "... #{ link_to '(continue)', '#' }"), Sanitize::Config::BASIC).html_safe %>

は有効なHTMLで抜粋を与えます。 私はそれが誰かに助けを願っています。

あなたのためにこれの世話をする HTMLTruncator の名前の宝石が用意されました。私はポストの抜粋などを表示するためにそれを使用しました、そして、それは非常に堅牢です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top