Topic embedding braucht etwas Liebe

Ich wurde heute daran erinnert, nachdem ich auf die Schaltfläche „Vollständigen Beitrag anzeigen“ für Introducing Discourse AI geklickt hatte. Der vollständige Beitrag, der auf Discourse angezeigt wird, enthält keine Bilder und viele Überschriften fehlen. Zu der Verwirrung trägt bei, dass Bildunterschriften angezeigt werden, aber ohne die zugehörigen Bilder.

Es ist möglicherweise möglich, das Problem auf Meta für seinen (Ghost?) Blog zu beheben, indem die Website-Einstellung von Meta allowed embed selectors angepasst wird: Configuring allowed embed selectors. Aus vergangener Erfahrung weiß ich, dass die Anpassung dieser Einstellung ein kniffliger Prozess sein kann. Wenn Sie versuchen, sie anzupassen, achten Sie genau auf die Ergebnisse.

Discourse hat ein großes Potenzial, als Kommentarsystem für externe Beiträge zu fungieren, aber um dies gut zu machen, muss das Klicken auf die Schaltfläche „Vollständigen Beitrag anzeigen“ zuverlässig alle Elemente des externen Beitrags abrufen. Ich denke, das Problem ist, dass das Ruby Readability Gem, das zum Parsen externer Beiträge verwendet wird, nicht für den Zweck bestimmt ist, für den Discourse es verwendet. Es wird auch nicht aktiv gepflegt: GitHub - cantino/ruby-readability: Port of arc90's readability project to Ruby.

3 „Gefällt mir“

Ja, an diesem Punkt müssen wir entweder zu etwas anderem wechseln, das es etwas besser macht, oder die Einbettungsstrategie ändern, um das
Show Full Post
in ein
Read Full Post
zu ändern, das ein einfacher Link zum Originalbeitrag ist. Es ist vielleicht sinnlos, sich nach allen möglichen Einbettungsproblemen auf jeder Website herumzuschlagen.

4 „Gefällt mir“

@sam habe das gerade behoben, schau mal.

3 „Gefällt mir“

Wir bereiten die Veröffentlichung unseres Blogs auf Ghost vor und nutzen die Ghost-zu-Discourse-Integrationen. Wir freuen uns sehr über diese Änderung!

4 „Gefällt mir“

Die Bilder werden jetzt geladen. Ich bin nicht gut in Rätseln vom Typ „Finde den Unterschied“, aber ich sehe immer noch einige Unterschiede:

  • Titel Semantic Related Topics fehlt
  • Titel Community Sentiment fehlt
  • Fehlende unsortierte Liste im Abschnitt Modules Providers
  • Titel Installing Discourse AI on your community fehlt

Idealerweise sollte die Aufforderung „Sign up for our newsletter“ aus dem eingebetteten Beitrag ausgeschlossen werden.

Die Möglichkeit, den eingebetteten Beitrag einfach zu zitieren, scheint wichtig zu sein. Wenn ich jetzt darüber nachdenke, bin ich mir nicht sicher, was das erwartete Verhalten ist, wenn die Schaltflächen „Erweitern/Einklappen“ und „Zum Beitrag springen“ für die Zitate eines eingebetteten Beitrags angeklickt werden.

Das ist ein kniffliges Problem. Es sollte so einfach sein wie das Bereinigen des HTML, das im article oder main-Element eines Beitrags enthalten ist, aber ich vermute, dass es mit diesem Ansatz immer noch Probleme geben würde. Zum Beispiel wäre eine spezielle Behandlung erforderlich, um die Duplizierung des h1-Elements eines Blogbeitrags zu verhindern, wenn der header innerhalb des article existiert.

1 „Gefällt mir“

Ich glaube, das passiert auch in readability.js, das ist die Leseansicht von Firefox:

<h2 id="installing-discourse-ai-on-your-community">
      <strong>Installing Discourse AI on your community</strong>
    </h2>

Ich werde sehen, ob es eine einfache Möglichkeit gibt, dies zu beheben…

Ich bin mir da nicht sicher… aber wenn wir das wirklich wirklich wollen, können wir .discourse-newsletter-signup zu blocked_embed_selectors hinzufügen.

4 „Gefällt mir“

Ja, readablity.js basiert auf demselben Code wie GitHub - cantino/ruby-readability: Port of arc90's readability project to Ruby, daher wird wahrscheinlich dieselbe Logik zum Entfernen dieser Elemente verwendet. readablity.js leistet im Allgemeinen bessere Arbeit als Ruby Readability.

Der E-Mail-CTA ist verwirrend, da die E-Mail-Eingabe aus dem eingebetteten Beitrag entfernt wird. Technisch gesehen bin ich mir nicht sicher, ob der CTA in den article gehört.

1 „Gefällt mir“

Ich stoße das hier nur hoch, da ich @simon zustimme, dass dies irgendwann überdacht werden sollte.

Ein erheblicher Teil der Supportanfragen für das WP Discourse Plugin betrifft tatsächlich Probleme mit der Lesbarkeits-Crawling in irgendeiner Form.

Ich denke, das fasst meine Intuition hier gut zusammen.

Das gesagt, habe ich im Moment keine großartige Lösung außer dieser.

Aber ich bin daran interessiert, zu einer besseren Lösung als dem Status quo beizutragen, da dies die Supportarbeit für WP Discourse reduzieren würde.

1 „Gefällt mir“

Sie schauen sich zwar Probleme an, aber sie beheben sie nur langsam…

Es ist nicht allzu schwer, MiniRacer so einzurichten, dass es Lesbarkeit zusammenfasst … Ich habe einen Prototyp davon gemacht.

Es ist möglich, dass wir zu dieser Implementierung übergehen könnten, aber wir sind auch schon abgewichen, sodass wir am Ende Funktionen aufgeben würden.

Das ist kein leicht zu lösendes Problem.

2 „Gefällt mir“

Ja, fair, aber ich glaube, das wird ein endloses Whac-a-Mole-Spiel. Es wird immer eine Version von geben:

Der Beitrag auf meiner Website sieht aus wie X und wenn ich auf „Vollständigen Beitrag anzeigen“ klicke, sieht er aus wie Y, und ich möchte, dass sie identisch sind.

Ich schätze, meine tiefere Frage ist, ob es einen wirklichen Nutzen für diese Funktionalität gibt, die niemals perfekt sein wird, gegenüber

Indem Sie daraus eine Schaltfläche „Vollständigen Beitrag anzeigen“ machen, erwarten die Leute eine Treue, die Discourse niemals vollständig liefern kann. Meine Sorge gilt eher dem Erwartungsmanagement.

Ich vermute, Sie fordern die Entfernung der Einbettungsfunktion. Ich bin mir nicht sicher, ob ich dafür bin. Ich denke, Websites, die sehr unordentliche Inhalte einbetten, sollten diese einfache Form „Link zum Original“ verwenden. Websites, die besser strukturierte Inhalte einbetten, können jedoch den Lesermodus nutzen, auch wenn er unvollkommen ist.

1 „Gefällt mir“

Nicht unbedingt. Ich sage, es muss ein besseres Erwartungsmanagement geben.

99 % der Leute, die eine Website betreiben, wissen nicht, ob ihr HTML semantisch genug ist, um von einem Gem wie Readability leicht analysiert zu werden, oder sogar, dass dies bestimmt, wie die Funktion funktioniert. Die Standardannahme der Benutzer ist, dass es ein Problem „in Discourse“ (oder häufiger im WP Discourse-Plugin) gibt, wenn es keine 100%ige Übereinstimmung zwischen dem Beitrag auf ihrer Website und dem Inhalt gibt, der angezeigt wird, wenn der Benutzer auf „Vollständigen Beitrag anzeigen“ klickt.

Eine Option wie ein einfach zu aktivierender und vielleicht standardmäßiger CTA „Vollständigen Beitrag lesen“ würde, denke ich, helfen.

2 „Gefällt mir“

Was ich damit meinte, ist, dass Ruby Readability „ein Werkzeug zur Extraktion des primären lesbaren Inhalts einer Webseite“ ist. Für den Fall einer Website, die Beiträge an Discourse veröffentlicht, denke ich, dass man davon ausgehen kann, dass der primäre lesbare Inhalt der Webseite bekannt ist und durch einen äußeren CSS-Selektor definiert werden kann. Zum Beispiel article, .entry-content, .post usw.

Die Art von Werkzeug, die ich mir vorstelle, würde es Websites einfach ermöglichen, einen äußeren Selektor für den Inhalt ihres Beitrags zu definieren und dann das HTML zu bereinigen, das sich innerhalb dieses Selektors befand. Eine etwas ausgefeiltere Version würde es Websites ermöglichen, innere Selektoren zu definieren, die sie von Discourse ausschließen möchten.

Auf meiner WordPress-Website habe ich einen Beitrag mit einer völlig standardmäßigen Markup. Ich möchte alles veröffentlichen, was sich im .entry-content-Div befindet, an Discourse. Es funktioniert fast, aber ich kann die Einstellung allowed embed selector in Discourse nicht so konfigurieren, dass die Listenelemente des Beitrags abgerufen werden. Das ist die Art von Problem, bei der Websites Schwierigkeiten haben. Ohne die Möglichkeit, Rails.cache.clear auszuführen, ist die Konfiguration wirklich schwierig.

Das Veröffentlichen des Beitrags als Onebox ist dafür eine vernünftige Lösung.

Bearbeiten: Die Option debug ist nützlich, um herauszufinden, was vor sich geht: GitHub - cantino/ruby-readability: Port of arc90's readability project to Ruby. Für den Fall der ausgeschlossenen Listen in meinem WordPress-Beitrag:

Conditionally cleaned ul#. with weight 0 and content score 0 because it has too many links for its weight (0).

Es ist jedoch eine völlig legitime Liste.

Ein häufig nachgefragtes Feature bei erweiterten Embeds ist die Möglichkeit, YouTube-Videos im erweiterten Inhalt erscheinen zu lassen. Dies zu verhindern, ist fest im Gem codiert: ruby-readability/lib/readability.rb at master · cantino/ruby-readability · GitHub. Ich bin mir nicht sicher, ob es sich lohnt, einen PR zu erstellen, um diese Liste mit einer Option überschreiben zu können.

2 „Gefällt mir“

Ich werde mich damit nicht zu sehr beschäftigen, aber ich habe am Wochenende Nokogiri für etwas anderes verwendet. Es macht irgendwie süchtig. Ich dachte, ich schaue mir den Einbettungscode an, während Nokogiri mir noch frisch im Gedächtnis ist.

Mein Interesse daran ist, dass ich gerne sehen würde, wie Discourse von Nachrichten- und Blogging-Websites häufiger genutzt wird. Wenn das passieren würde, kann ich mir vorstellen, dass neue Websitebesitzer von der aktuellen Einbettungsfunktionalität frustriert werden. Hier ist eine Idee zur Verbesserung:

Fügen Sie dem EmbeddableHost-Modell zwei neue optionale Attribute hinzu:

  • target_selector: Der äußere CSS-Selektor, der den einzubettenden Inhalt enthält
  • exclude_selectors: Eine Liste von CSS-Selektoren, die aus dem durch target_selector ausgewählten Inhalt ausgeschlossen werden sollen.

Ein “Konfigurieren”-Button sollte zu jeder Zeile von Embeddable Host auf der Admin / Embedding-Seite hinzugefügt werden. Das Klicken auf diesen Button öffnet eine Seite, die der Seite E-Mails / Vorschau Zusammenfassung ähnelt.

Die Seite Host konfigurieren würde ein Formular mit Feldern für die Eingabe der target_selector- und exclude_selectors-Einstellungen des Hosts sowie ein URL-Feld enthalten, das es ermöglicht, die angegebenen Werte gegen eine bestimmte Webseite zu testen. Der Test würde im Wesentlichen nur TopicEmbed.parse_html mit den angegebenen target_selector- und exclude_selectors-Werten ausführen und dann die Ergebnisse anzeigen.


Änderungen am parse_html-Code sind leicht zu testen. Hier ist ein möglicher Ansatz. Beachten Sie, dass dieser Code nur ein Proof of Concept ist:

bearbeitet in topic_embed.rb (discourse/app/models/topic_embed.rb at main · discourse/discourse · GitHub)

###########################################################################
    # `target_selector` und `exclude_selectors` würden idealerweise aus dem `EmbeddableHost`-Datensatz der Domain gefunden werden
    # diese speziellen Einstellungen wurden zum Testen gegen boingboing.net verwendet
    target_selector = 'article'
    exclude_selectors = ['.article-header, .share-comments-container', '.boing-single-post-rev-content', '.next-post-list-container', '.boing-end-of-article-container-on-single-post-pages']

    if defined?(target_selector) && target_selector.present?
      read_doc = article_content(html, target_selector, exclude_selectors)
    else
      # Fallback auf Readability, wenn `target_selector` für den Host nicht gesetzt ist
      read_doc = Readability::Document.new(html, opts)
    end
    ###########################################################################

Um ohne Erstellung einer neuen Klasse zu testen, hier eine einfache article_content-Methode, die der TopicEmbed-Klasse hinzugefügt wurde:

  def self.article_content(html, target_selector, exclude_selectors = [])
    doc = Nokogiri::HTML(html)
    # Kommentare und Skript-Tags entfernen
    doc.xpath('//comment()').each { |i| i.remove }
    doc.css("script, style").each { |i| i.remove }

    # NodeSet für den target_selector abrufen
    # vielleicht hier auf Readability zurückgreifen, wenn das zurückgegebene Set leer ist
    selected_nodes = doc.css(target_selector)

    # Knoten ausschließen
    unless exclude_selectors.empty?
      selected_nodes.css(*exclude_selectors).each do |node|
        node.remove
      end
    end

    # Bildgrößen behandeln, muss möglicherweise verbessert werden
    selected_nodes.css('img').each do |img|
      img.remove_attribute('width')
      img.remove_attribute('height')
    end

    # nur zum Spaß, iframes zulassen, wenn ihre Quelle erlaubt ist
    # verwende `[data-sanitized="true"]`, um zu verhindern, dass iframes im remove_empty_nodes-Schritt entfernt werden
    allowed_iframe_sources = SiteSetting.allowed_iframes.split('|')
    selected_nodes.css('iframe').each do |iframe|
      allowed = allowed_iframe_sources.any? do |allowed_source|
        iframe['src'].start_with?(allowed_source)
      end

      if allowed
        iframe['data-sanitized'] = 'true'
        iframe['width'] = '690'
        iframe['height'] = '388'
      else
        iframe.remove
      end
    end

    # leere 'p'- und 'div'-Knoten entfernen
    selected_nodes.css('p', 'div').each do |node|
      node.remove if node.content.strip.empty? && !node.at_css('iframe[data-sanitized="true"]')
    end

    # die Knoten in eine Zeichenkette umwandeln und ein Objekt mit einer `content`-Methode zurückgeben
    content = selected_nodes.to_s
    OpenStruct.new(content: content)
  end

Ich bin ziemlich sicher, dass es nur ein wenig Bastelei an mehreren Domains erfordern würde, um es richtig zu machen. Die Ergebnisse, die ich bisher für BBS erzielt habe, sind gut.

Das Ziel ist es, etwas zu entwickeln, das Websitebesitzer leicht verstehen und selbst konfigurieren können. Mit diesem Ansatz gilt: Je spezifischer der target_selector ist, desto einfacher ist die Konfiguration der exclude_selectors. Zum Beispiel wäre für eine WordPress-Website, wenn .entry-content als target_selector ausgewählt würde, keine weitere Konfiguration erforderlich. Wenn Websitebesitzer mehr als nur das grundlegende .entry-content-HTML erhalten möchten, könnten sie auf der Seite Host konfigurieren herausfinden, wie das geht.

Das einzige wirkliche Problem, das ich sehe, sind Hosts mit sehr inkonsistentem HTML. Dieser Fall könnte durch die Beibehaltung von Ruby Readability als Fallback behandelt werden.