La riscrittura dei link affiliati (e qualsiasi hook post_process_cooked) viene ignorata per i contenuti dei post localizzati/tradotti

Riepilogo

Quando la localizzazione dei contenuti è abilitata, il tag Amazon del plugin affiliato (e, più in generale, qualsiasi plugin che riscrive l’HTML elaborato tramite l’evento post_process_cooked) viene applicato all’HTML elaborato originale di un post, ma non al suo HTML elaborato tradotto PostLocalization. I lettori che visualizzano un post in una lingua tradotta vedono quindi il link grezzo e non contrassegnato, il che significa che la commissione affiliata viene persa per ogni visualizzazione tradotta.

La causa principale è che i contenuti tradotti vengono elaborati tramite un secondo processore separato (LocalizedCookedPostProcessor) che non attiva mai l’evento post_process_cooked.

Ambiente

  • Discourse: core main @ 978e9b2e5dc (2026-07-15); confermato anche sulla versione 2026.7.0 @ 7c06c1528 (2026-07-10). Nessuna modifica rilevante tra le due.
  • Plugin: discourse-affiliate (incluso nella directory plugins/ del core), con affiliate_amazon_de (o qualsiasi affiliate_amazon_*) impostato su un tag valido.
  • Impostazioni: content_localization_enabled = true, content_localization_supported_locales include almeno una lingua diversa da quella originale del post.
  • Ambito: lato server (elaborazione post). Indipendente da dispositivo/SO/browser; si riproduce in Modalità Sicura e senza temi, poiché avviene nella pipeline di elaborazione, non nel frontend.

Passaggi per riprodurre il problema

  1. Abilita content_localization_enabled e aggiungi una seconda lingua supportata (ad esempio, post originali in de, traduzione in en).
  2. Configura discourse-affiliate: imposta il tag Amazon per il marketplace rilevante (ad esempio affiliate_amazon_de = mytag-21).
  3. Crea un post il cui contenuto grezzo contiene un link a un prodotto Amazon, ad esempio https://www.amazon.de/-/en/…/dp/B0C3WGSSWC.
  4. Visualizza il post nella sua lingua originale e ispeziona l’attributo href dell’ancora Amazon.
  5. Genera/fornisci la versione tradotta dello stesso post (tramite il selettore lingua o lasciando che la traduzione venga creata) e ispeziona l’attributo href della stessa ancora.

Risultato effettivo

  • Elaborato originale: …/dp/B0C3WGSSWC?tag=mytag-21 — tag affiliato presente. :white_check_mark:
  • PostLocalization elaborato (tradotto): …/dp/B0C3WGSSWC — nessun tag, nessuna riscrittura affiliata. :cross_mark:

(Confermato direttamente nel DB: per un post interessato, posts.cooked contiene l’URL con il tag, mentre ogni riga post_localizations.cooked per quel post contiene l’URL senza tag.)

Risultato atteso

L’HTML elaborato tradotto dovrebbe ricevere la stessa riscrittura dei link dell’originale, in modo che il tag affiliato (e qualsiasi altra trasformazione post_process_cooked) sia presente in ogni lingua visualizzata dal lettore.

Causa principale

Il plugin affiliato riscrive i link solo all’interno dell’evento post_process_cooked:

# 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

Tale evento viene attivato da un unico punto, l’elaborazione della lingua originale:

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

I contenuti tradotti, tuttavia, vengono elaborati da un processore diverso, accodato da PostLocalizationCreator/PostLocalizationUpdater come Jobs::ProcessLocalizedCooked:

# 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 non attiva mai post_process_cooked e non c’è nessun DiscourseEvent.trigger in alcun punto del percorso di elaborazione della localizzazione — quindi nessun plugin che si affida a tale evento partecipa ai contenuti tradotti. Questo è un gap generale: oggi influisce sul tagging affiliato, ma allo stesso modo su qualsiasi plugin che muta l’HTML elaborato tramite post_process_cooked (decoratori di link, riscritture badge/mention, ecc.).

Soluzione suggerita

Far partecipare l’elaborazione localizzata alla stessa riscrittura link/DOM dell’elaborazione originale. Entrambe le opzioni risolvono il problema:

  1. Emettere un evento agganciabile dal processore localizzato — attivare post_process_cooked (o un dedicato post_process_localized_cooked) all’interno di LocalizedCookedPostProcessor#post_process, in modo che i plugin esistenti funzionino sulle traduzioni senza modifiche per ogni plugin. (Se si preferisce un nuovo evento per evitare effetti collaterali di elaborazione doppia, i plugin possono opt-in.)
  2. Eseguire la riscrittura affiliata nel percorso localizzato, ad esempio riutilizzando AffiliateProcessor.apply su @doc.css("a[href]") in LocalizedCookedPostProcessor#post_process dopo i passaggi onebox/immagine.

L’opzione 1 è la soluzione più generale, poiché lo stesso gap influisce su ogni consumatore di post_process_cooked, non solo sull’affiliato.

Note aggiuntive

  • Un sito che ha già traduzioni interessate dovrà rieseguire l’elaborazione delle righe PostLocalization esistenti dopo la correzione (ad esempio, riaccodare Jobs::ProcessLocalizedCooked con recook: true) per aggiungere i tag ai post già tradotti.
  • Si riproduce in modo coerente (non intermittente) ogni volta che un post con un link idoneo all’affiliato viene fornito in una lingua tradotta.