Frage

Ich habe eine Seite, die News-Artikel auflistet. So schneiden nach unten auf die Länge der Seite, ich will nur einen Teaser angezeigt werden (die ersten 200 Wörter / 600 Buchstaben des Artikels) und zeigt dann eine „mehr ...“ -Link, dass, wenn sie angeklickt, wird der Rest des erweitern Artikel in einer jQuery / Javascript Art und Weise. Nun habe ich alles, was herausgefunden und auch die folgende Hilfsmethode auf etwas Paste Seite gefunden, die sicherstellen werden, dass der News-Artikel (string) nicht direkt in der Mitte eines Wortes zerhackt:

 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

Das Problem, das ich habe, ist, dass die News-Artikel Stellen, die ich von der DB erhalten werden formatiert HTML. Also, wenn ich unglücklich bin, wird der oben Helfer dort meinen Artikel String direkt in der Mitte eines HTML-Tags und legen Sie die „mehr ...“ string zerhacken (zB zwischen „“), denen korrupte meine HTML-Datei auf der Seite .

Gibt es eine Möglichkeit, um dieses oder ist es ein Plugin gibt, die ich Auszüge / Teasern aus einer HTML-Zeichenfolge zu erzeugen, verwenden kann?

War es hilfreich?

Lösung 3

Vielen Dank für Ihre Antworten! Doch in der Zwischenzeit stieß ich auf dem jQuery HTML Truncator Plugin , die meine Zwecke perfekt passt und verschiebt die Verkürzung auf der Client-Seite. Es ist nicht einfacher: -)

Andere Tipps

Sie können eine Kombination von verwenden Sanitize und kürzen .

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

Ich mache eine ähnliche Aufgabe, wo ich Blog-Posts haben und ich möchte nur einen kurzen Ausschnitt zeigen. Also meiner Meinung nach muss ich einfach:

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

Das entfernt die HTML-Tags aus, gibt mir die ersten 150 Zeichen und in der Ansicht behandelt, so dass es MVC freundlich ist.

Viel Glück!

Meine Antwort hier sollte Arbeit tun. Die ursprüngliche Frage (err, von mir gefragt) etwa Abschlag Kürzen, aber ich beenden den Abschlag Umwandlung bis HTML dann, dass Kürzen, so sollte es funktionieren.

Natürlich, wenn Ihre Website viel Verkehr wird, sollten Sie den Auszug Cache (vielleicht, wenn die Post erstellt / aktualisiert, können Sie den Ausschnitt in der Datenbank speichern können?), Würde dies auch bedeuten, könnten Sie dem Benutzer erlauben, zu ändern oder geben Sie ihre eigenen Auszug

Verbrauch:

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

.. und der Code (von der anderen Antwort kopiert):

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

Möchten Sie einen komplexeren Parser schreiben, wenn Sie nicht wollen, in der Mitte von HTML-Elementen spalten. es hätte sich daran zu erinnern, wenn sie in der Mitte eines <> Block und wenn ihr zwischen zwei Markierungen ist.

auch wenn man das täte, würden Sie immer noch Probleme haben. wenn einige setzen den ganzen Artikel in ein HTML-Element, da der Parser könne nicht es überall geteilt, wegen des fehlenden schließenden Tages.

, wenn es möglich ist, überhaupt würde ich versuche keine Tags in den Artikeln zu setzen oder es um Schlagworte zu halten, die (nicht <div> usw.) enthalten nicht nichts. auf diese Weise würden Sie müssen nur überprüfen, ob Sie in der Mitte eines Tags sind, die ziemlich einfach:

  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

ich hätte die HTML hygienisiert und extrahiert den ersten Satz. Vorausgesetzt, dass Sie einen Artikel Modell, mit einem ‚Körper‘ Attribut, das den HTML enthält:

# 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

Dies würde konvertieren " Das ist ein wichtig Artikel! Und hier ist der Rest des Artikels." in „Dies ist ein wichtiger Beitrag“.

Ich löste dies mit folgenden Lösung

Installieren gem 'sanieren'

gem install sanitize

und verwendeten Code folgen, hier Körper wird Text HTML-Tags enthalten.

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

Gibt Auszug mit gültigen html. Ich hoffe, es hilft jemand.

Es gibt jetzt ein Juwel namens HTMLTruncator , die für Sie kümmern sich um das dauert. Ich habe es Post Ausschnitte und dergleichen angezeigt werden, und es ist sehr robust.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top