Das Umschreiben von Affiliate-Links (und jeder post_process_cooked-Hook) wird für lokalisierte/übersetzte Beitragsinhalte übersprungen

Zusammenfassung

Wenn die Inhaltslokalisierung aktiviert ist, wird das Amazon-Tag des Affiliate-Plugins (und allgemeiner jedes Plugin, das den fertiggestellten HTML-Code über das post_process_cooked-Ereignis umschreibt) auf den originalen fertiggestellten HTML-Code eines Beitrags angewendet, jedoch nicht auf dessen übersetzten PostLocalization-HTML-Code. Leser, die einen Beitrag in einer übersetzten Sprache ansehen, sehen daher den rohen, nicht getaggten Link, was bedeutet, dass bei jedem Aufruf einer übersetzten Version die Affiliate-Provision verloren geht.

Die Ursache liegt darin, dass übersetzte Inhalte durch einen zweiten, separaten Prozessor (LocalizedCookedPostProcessor) verarbeitet werden, der das post_process_cooked-Ereignis niemals auslöst.

Umgebung

  • Discourse: core main @ 978e9b2e5dc (2026-07-15); ebenfalls bestätigt auf der 2026.7.0-Version @ 7c06c1528 (2026-07-10). Keine relevanten Änderungen zwischen beiden.
  • Plugin: discourse-affiliate (im plugins/-Verzeichnis des Cores enthalten), mit affiliate_amazon_de (oder einem beliebigen affiliate_amazon_*) auf ein gültiges Tag gesetzt.
  • Einstellungen: content_localization_enabled = true, content_localization_supported_locales enthält mindestens eine Sprache außer der Originalsprache des Beitrags.
  • Umfang: serverseitig (Beitragsverarbeitung). Unabhängig von Gerät/OS/Browser; tritt im Safe-Modus und ohne Theme auf, da es in der Verarbeitungs-Pipeline (Cook-Pipeline) und nicht im Frontend geschieht.

Schritte zur Reproduktion

  1. Aktiviere content_localization_enabled und füge eine zweite unterstützte Sprache hinzu (z. B. Originalbeiträge in de, Übersetzung nach en).
  2. Konfiguriere discourse-affiliate: Setze das Amazon-Tag für den relevanten Markt (z. B. affiliate_amazon_de = mytag-21).
  3. Erstelle einen Beitrag, dessen Rohdaten einen Amazon-Produktlink enthalten, z. B. https://www.amazon.de/-/en/…/dp/B0C3WGSSWC.
  4. Betrachte den Beitrag in seiner Originalsprache und prüfe das href-Attribut des Amazon-Links.
  5. Generiere/liefere die übersetzte Version desselben Beitrags (über den Sprachumschalter oder durch automatisches Erstellen der Übersetzung) und prüfe das href-Attribut desselben Links.

Tatsächliches Ergebnis

  • Originaler HTML-Code: …/dp/B0C3WGSSWC?tag=mytag-21 — Affiliate-Tag vorhanden. :white_check_mark:
  • PostLocalization-HTML-Code (übersetzt): …/dp/B0C3WGSSWC — kein tag, keine Affiliate-Umschreibung. :cross_mark:

(Direkt in der Datenbank bestätigt: Für einen betroffenen Beitrag enthält posts.cooked die getaggte URL, während jede post_localizations.cooked-Zeile für diesen Beitrag die reine URL enthält.)

Erwartetes Ergebnis

Der übersetzte HTML-Code sollte dieselbe Link-Umschreibung erhalten wie der Originalcode, sodass das Affiliate-Tag (und jede andere post_process_cooked-Transformation) in jeder Sprache vorhanden ist, in der ein Leser den Beitrag ansehen kann.

Ursache

Das Affiliate-Plugin schreibt Links nur innerhalb des post_process_cooked-Ereignisses um:

# plugins/discourse-affiliate/plugin.rb
on(:post_process_cooked) do |doc, post|
  doc.css("a[href]").each { |a| a["href"] = AffiliateProcessor.apply(a["href"]) }
  true
end

Dieses Ereignis wird genau an einer Stelle ausgelöst, bei der Verarbeitung der Originalsprache:

# lib/cooked_post_processor.rb:50
DiscourseEvent.trigger(:post_process_cooked, @doc, @post)

Übersetzte Inhalte werden jedoch von einem anderen Prozessor verarbeitet, der von PostLocalizationCreator/PostLocalizationUpdater als Jobs::ProcessLocalizedCooked in die Warteschlange gestellt wird:

# lib/localized_cooked_post_processor.rb
def post_process
  post_process_oneboxes
  post_process_images
  @post_localization.link_post_uploads(fragments: @doc)
end

LocalizedCookedPostProcessor#post_process löst niemals post_process_cooked aus, und es gibt kein DiscourseEvent.trigger irgendwo im Lokalisierungs-Verarbeitungspfad — daher nimmt kein Plugin, das sich auf dieses Ereignis verlässt, an der Verarbeitung übersetzter Inhalte teil. Dies ist ein allgemeines Defizit: Es betrifft heute das Affiliate-Tagging, aber gleichermaßen jedes Plugin, das den HTML-Code über post_process_cooked verändert (Link-Dekorierer, Badge-/Erwähnungs-Umschreibungen usw.).

Vorgeschlagene Lösung

Lasse die Lokalisierungs-Verarbeitung an derselben Link-/DOM-Umschreibung teilhaben wie die Originalverarbeitung. Beide Optionen lösen das Problem:

  1. Ein hookbares Ereignis vom Lokalisierungs-Prozessor auslösen — löse post_process_cooked (oder ein dediziertes post_process_localized_cooked) innerhalb von LocalizedCookedPostProcessor#post_process aus, sodass bestehende Plugins ohne plugin-spezifische Änderungen auch auf Übersetzungen funktionieren. (Wenn ein neues Ereignis bevorzugt wird, um doppelte Verarbeitungseffekte zu vermeiden, können Plugins sich dafür entscheiden.)
  2. Führe die Affiliate-Umschreibung im Lokalisierungs-Pfad aus, z. B. wende AffiliateProcessor.apply auf @doc.css("a[href]") in LocalizedCookedPostProcessor#post_process nach den Onebox-/Bild-Verarbeitungsschritten an.

Option 1 ist die allgemeinere Lösung, da dasselbe Defizit jeden Verbraucher von post_process_cooked betrifft, nicht nur Affiliate-Plugins.

Zusätzliche Hinweise

  • Eine Site, die bereits betroffene Übersetzungen hat, muss bestehende PostLocalization-Einträge nach der Korrektur erneut verarbeiten (z. B. Jobs::ProcessLocalizedCooked mit recook: true erneut in die Warteschlange stellen), um Tags in bereits übersetzten Beiträgen nachzutragen.
  • Tritt konsistent (nicht intermittierend) auf, wann immer ein Beitrag mit einem affiliate-fähigen Link in einer übersetzten Sprache ausgeliefert wird.