Resumen
Cuando la localización de contenido está habilitada, la etiqueta de Amazon del plugin de afiliados (y, en general, cualquier plugin que reescriba HTML procesado mediante el evento post_process_cooked) se aplica al HTML procesado original de una publicación, pero no a su HTML procesado PostLocalization traducido. Por lo tanto, los lectores que ven una publicación en un idioma traducido observan el enlace sin procesar y sin etiqueta, lo que significa que se pierde la comisión de afiliado en cada visualización traducida.
La causa raíz es que el contenido traducido se procesa a través de un segundo procesador separado (LocalizedCookedPostProcessor) que nunca activa el evento post_process_cooked.
Entorno
- Discourse: rama principal
main@978e9b2e5dc(2026-07-15); también confirmado en la rama2026.7.0@7c06c1528(2026-07-10). No hay cambios relevantes entre ambas. - Plugin:
discourse-affiliate(incluido en el directorioplugins/del núcleo), conaffiliate_amazon_de(o cualquieraffiliate_amazon_*) configurado con una etiqueta válida. - Configuración:
content_localization_enabled = true,content_localization_supported_localesincluye al menos un idioma diferente al original de la publicación. - Alcance: lado del servidor (procesamiento de publicaciones). Independiente del dispositivo/SO/navegador; se reproduce en Modo Seguro y sin temas, ya que ocurre en la pipeline de procesamiento, no en el front end.
Pasos para reproducir
- Habilita
content_localization_enabledy añade un segundo idioma compatible (por ejemplo, publicaciones originales ende, traducción aen). - Configura
discourse-affiliate: establece la etiqueta de Amazon para el mercado relevante (por ejemplo,affiliate_amazon_de = mytag-21). - Crea una publicación cuyo contenido sin procesar contenga un enlace de producto de Amazon, por ejemplo,
https://www.amazon.de/-/en/…/dp/B0C3WGSSWC. - Visualiza la publicación en su idioma original e inspecciona el atributo
hrefdel enlace de Amazon. - Genera/sirve la versión traducida de la misma publicación (mediante el selector de idioma, o dejando que se cree la traducción) e inspecciona el atributo
hrefdel mismo enlace.
Resultado actual
- HTML procesado original:
…/dp/B0C3WGSSWC?tag=mytag-21— etiqueta de afiliado presente.
- HTML procesado
PostLocalization(traducido):…/dp/B0C3WGSSWC— sintag, sin reescritura de afiliado en absoluto.
(Confirmado directamente en la base de datos: para una publicación afectada, posts.cooked contiene la URL con etiqueta, mientras que cada fila post_localizations.cooked para esa publicación contiene la URL sin etiqueta.)
Resultado esperado
El HTML procesado traducido debería recibir la misma reescritura de enlaces que el original, de modo que la etiqueta de afiliado (y cualquier otra transformación de post_process_cooked) esté presente en cada idioma que pueda ver un lector.
Causa raíz
El plugin de afiliados reescribe enlaces únicamente dentro del 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
Dicho evento se activa desde un único lugar, el procesamiento del idioma original:
# lib/cooked_post_processor.rb:50
DiscourseEvent.trigger(:post_process_cooked, @doc, @post)
Sin embargo, el contenido traducido se procesa mediante un procesador diferente, encolado desde PostLocalizationCreator/PostLocalizationUpdater como 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 nunca activa post_process_cooked, y no hay ningún DiscourseEvent.trigger en ninguna parte de la ruta de procesamiento de localización; por lo tanto, ningún plugin que dependa de ese evento participa en el contenido traducido. Esta es una brecha general: afecta a la etiquetado de afiliados hoy, pero también a cualquier plugin que modifique HTML procesado a través de post_process_cooked (decoradores de enlaces, reescritura de insignias/menciones, etc.).
Corrección sugerida
Hacer que el procesamiento de localización participe en la misma reescritura de enlaces/DOM que el procesamiento original. Cualquiera de las siguientes opciones lo resuelve:
- Emitir un evento accionable desde el procesador de localización — activar
post_process_cooked(o unpost_process_localized_cookeddedicado) dentro deLocalizedCookedPostProcessor#post_process, para que los plugins existentes funcionen en traducciones sin cambios específicos por plugin. (Si se prefiere un nuevo evento para evitar efectos secundarios de procesamiento doble, los plugins pueden optar por incorporarse.) - Ejecutar la reescritura de afiliados en la ruta de localización, por ejemplo, reutilizar
AffiliateProcessor.applysobre@doc.css("a[href]")enLocalizedCookedPostProcessor#post_processdespués de los pasos de onebox/imágenes.
La opción 1 es la corrección más general, ya que la misma brecha afecta a cada consumidor de post_process_cooked, no solo a afiliados.
Notas adicionales
- Un sitio que ya tenga traducciones afectadas necesitará reprocesar las filas existentes de
PostLocalizationdespués de la corrección (por ejemplo, reencolarJobs::ProcessLocalizedCookedconrecook: true) para rellenar etiquetas en publicaciones ya traducidas. - Se reproduce de manera consistente (no intermitente) siempre que se sirva una publicación con un enlace elegible para afiliado en un idioma traducido.