Le bouton "Afficher le message complet" ne fonctionne pas dans les installations en sous-dossier

J’ai récemment déplacé notre installation Discourse dans un sous-dossier. Après cela, le bouton « Afficher le message complet » a cessé de fonctionner – vous cliquez pour développer le contenu, mais le message complet ne se charge pas.

Rien n’a changé dans mes configurations WP Discourse.

https://tecnoblog.net/comunidade/t/paramount-oferece-us-108-bilhoes-em-dinheiro-para-tomar-warner-da-netflix/157441

Lors de l’accès direct à l’URL intégrée dans le navigateur, il renvoie une erreur 404 :

https://tecnoblog.net/comunidade/posts/483289/expand-embed

1 « J'aime »

Ceci n’est pas lié, cette route ne répond qu’avec un type de contenu application/json. https://tecnoblog.net/comunidade/posts/483289/expand-embed.json renvoie

"\"\u003cdiv\u003e\u003cdiv\u003e\u003c/div\u003e\u003c/div\u003e\\n\u003chr\u003e\\n\u003csmall\u003eEste é um tópico de discussão auxiliar para a entrada original em \u003ca href='https://tecnoblog.net/noticias/paramount-oferece-us-108-bilhoes-em-dinheiro-para-tomar-warner-da-netflix'\u003ehttps://tecnoblog.net/noticias/paramount-oferece-us-108-bilhoes-em-dinheiro-para-tomar-warner-da-netflix\u003c/a\u003e\u003c/small\u003e\\n\""

Le \u003cdiv\u003e\u003cdiv\u003e\u003c/div\u003e\u003c/div\u003e devrait être le contenu.

Avez-vous également modifié l’URL du blog au passage ?

L’affichage onebox me semble également étrange, je m’attendrais à ce qu’il y ait un contenu tronqué mis en cache à la place, donc je suppose que body.present? est faux dans la condition ci-dessus.

Pouvez-vous entrer dans la console Rails et vérifier si TopicEmbed.where(topic_id: 157441).pick(:embed_url) vous montre la bonne URL de contenu du blog ?

Pouvez-vous repérer des erreurs pertinentes sur https://tecnoblog.net/comunidade/logs ?

2 « J'aime »

Ah, d’accord !

Elle retourne l’URL du post :

discourse(prod)=> TopicEmbed.where(topic_id: 157441).pick(:embed_url)
=> “``https://tecnoblog.net/noticias/paramount-oferece-us-108-bilhoes-em-dinheiro-para-tomar-warner-da-netflix”

Je ne pense pas qu’il y ait des erreurs liées dans le journal.

Nan ! L’URL du blog a toujours été tecnoblog.net

Il est également bon de mentionner que l’IP du serveur est contournée dans le pare-feu de CF :

2 « J'aime »

J’ai dû déboguer ce genre de problèmes plusieurs fois et c’est compliqué, alors soyez patient avec moi.

Exécutez le script suivant et partagez le résultat ici

# Remplacez par l'ID du sujet ou l'URL que vous déboguez
topic_id = 386983

# 1. Vérifier si TopicEmbed existe et son contenu
te = TopicEmbed.find_by(topic_id: topic_id)
puts "TopicEmbed existe : #{te.present?}"
puts "URL de l'intégration : #{te&.embed_url}"
puts "Cache de contenu présent : #{te&.embed_content_cache.present?}"
puts "Longueur du cache de contenu : #{te&.embed_content_cache&.length || 0}"
puts "SHA1 du contenu : #{te&.content_sha1}"

# 2. Vérifier le contenu mis en cache réel (500 premiers caractères)
puts "\n--- Aperçu du contenu mis en cache ---"
puts te&.embed_content_cache&.truncate(500)

# 3. Essayer de récupérer depuis l'URL distante
if te&.embed_url.present?
  puts "\n--- Tentative de récupération distante ---"
  begin
    response = TopicEmbed.find_remote(te.embed_url)
    puts "Récupération distante réussie : #{response.present?}"
    puts "Corps distant présent : #{response&.body.present?}"
    puts "Longueur du corps distant : #{response&.body&.length || 0}"
    puts "Titre distant : #{response&.title}"
    puts "Corps distant : #{response&.body&.truncate(500)}"
  rescue => e
    puts "Échec de la récupération distante : #{e.message}"
  end
end

# 4. Vérifier ce que retournerait expanded_for
if te.present?
  puts "\n--- Test de expanded_for ---"
  post = Post.find(te.post_id)

  # Vider le cache pour forcer une nouvelle récupération
  Discourse.cache.delete("embed-topic:#{topic_id}")

  begin
    expanded = TopicEmbed.expanded_for(post)
    puts "Contenu développé présent : #{expanded.present?}"
    puts "Longueur du contenu développé : #{expanded&.length || 0}"
  rescue => e
    puts "Échec de expanded_for : #{e.message}"
  end
end

# 5. Vérifier les paramètres du site
puts "\n--- Paramètres du site ---"
puts "embed_truncate: #{SiteSetting.embed_truncate}"
puts "allowed_embed_selectors: #{SiteSetting.allowed_embed_selectors}"
puts "blocked_embed_selectors: #{SiteSetting.blocked_embed_selectors}"

Ceci montrera pourquoi https://tecnoblog.net/comunidade/t/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento/157462?u=falco ne fonctionne pas

4 « J'aime »
discourse(prod)> # Replace with the topic ID or URL you’re debugging
discourse(prod)> topic_id = 386983
discourse(prod)>
discourse(prod)> # 1. Check if TopicEmbed exists and its content
discourse(prod)> te = TopicEmbed.find_by(topic_id: topic_id)
discourse(prod)> puts “TopicEmbed exists: #{te.present?}”
discourse(prod)> puts “Embed URL: #{te&.embed_url}”
discourse(prod)> puts “Content cache present: #{te&.embed_content_cache.present?}”
discourse(prod)> puts “Content cache length: #{te&.embed_content_cache&.length || 0}”
discourse(prod)> puts “Content SHA1: #{te&.content_sha1}”
discourse(prod)>
discourse(prod)> # 2. Check the actual cached content (first 500 chars)
discourse(prod)> puts “\n— Cached content preview —”
discourse(prod)> puts te&.embed_content_cache&.truncate(500)
discourse(prod)>
discourse(prod)> # 3. Try fetching from the remote URL
discourse(prod)* if te&.embed_url.present?
discourse(prod)*   puts “\n— Attempting remote fetch —”
discourse(prod)*   begin
discourse(prod)*     response = TopicEmbed.find_remote(te.embed_url)
discourse(prod)*     puts “Remote fetch success: #{response.present?}”
discourse(prod)*     puts “Remote body present: #{response&.body.present?}”
discourse(prod)*     puts “Remote body length: #{response&.body&.length || 0}”
discourse(prod)*     puts “Remote title: #{response&.title}”
discourse(prod)*     puts “Remote body: #{response&.body&.truncate(500)}”
discourse(prod)*   rescue => e
discourse(prod)*     puts “Remote fetch FAILED: #{e.message}”
discourse(prod)*   end
discourse(prod)* end
discourse(prod)>
discourse(prod)> # 4. Check what expanded_for would return
discourse(prod)* if te.present?
discourse(prod)*   puts “\n— Testing expanded_for —”
discourse(prod)*   post = Post.find(te.post_id)
discourse(prod)*
discourse(prod)*   # Clear cache to force fresh fetch
discourse(prod)*   Discourse.cache.delete(“embed-topic:#{topic_id}”)
discourse(prod)*
discourse(prod)*   begin
discourse(prod)*     expanded = TopicEmbed.expanded_for(post)
discourse(prod)*     puts “Expanded content present: #{expanded.present?}”
discourse(prod)*     puts “Expanded content length: #{expanded&.length || 0}”
discourse(prod)*   rescue => e
discourse(prod)*     puts “expanded_for FAILED: #{e.message}”
discourse(prod)*   end
discourse(prod)* end
discourse(prod)>
discourse(prod)> # 5. Check relevant settings
discourse(prod)> puts “\n— Site Settings —”
discourse(prod)> puts “embed_truncate: #{SiteSetting.embed_truncate}”
discourse(prod)> puts “allowed_embed_selectors: #{SiteSetting.allowed_embed_selectors}”
discourse(prod)> puts “blocked_embed_selectors: #{SiteSetting.blocked_embed_selectors}”
TopicEmbed exists: false
Embed URL:
Content cache present: false
Content cache length: 0
Content SHA1:

— Cached content preview —

— Site Settings —
embed_truncate: true
allowed_embed_selectors:
blocked_embed_selectors:
=> nil
discourse(prod)>

:thinking:

1 « J'aime »

Êtes-vous sûr que c’est le bon identifiant de sujet ? https://tecnoblog.net/comunidade/t/-/386983 mène à une page 404.

1 « J'aime »

Ah, c’est ça. Le sujet que j’ai lié est en fait le 157462.

Mes excuses !

Voici les résultats pour l’identifiant de sujet correct

TopicEmbed exists: true
Embed URL: https://tecnoblog.net/noticias/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento
Content cache present: true
Content cache length: 22
Content SHA1:

— Cached content preview —

<div><div></div></div>

— Attempting remote fetch —
Remote fetch success: true
Remote body present: true
Remote body length: 22
Remote title:
Remote body: 

— Testing expanded_for —
Expanded content present: true
Expanded content length: 309

— Site Settings —
embed_truncate: true
allowed_embed_selectors:
blocked_embed_selectors:
=> nil

Votre contournement de Cloudflare a-t-il fonctionné ? Il semble que le corps pour https://tecnoblog.net/noticias/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento ne fasse que 22 caractères, sans aucune balise de titre.

Oui ! Toutes les requêtes provenant du serveur discourse sont contournées :

Screenshot 2025-12-12 at 14.44.21

Ce que j’ai remarqué, c’est que l’URL d’intégration n’a pas de barre oblique finale à la fin. Toutes les URL devraient avoir la barre oblique finale.

Screenshot 2025-12-12 at 14.45.51

Alors, peut-être que discourse ne suit pas la redirection ?

Mais aussi, pourquoi enregistre-t-il l’URL sans la barre oblique finale ?

1 « J'aime »

C’est facile à tester, essayez

url = "https://tecnoblog.net/noticias/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento/"
response = TopicEmbed.find_remote(url)
puts "Récupération distante réussie : #{response.present?}"
puts "Corps distant présent : #{response&.body.present?}"
puts "Longueur du corps distant : #{response&.body&.length || 0}"
puts "Titre distant : #{response&.title}"
puts "Corps distant : #{response&.body&.truncate(500)}"

Je pense que ça fonctionne :

discourse(prod)> url = “https://tecnoblog.net/noticias/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento/”
discourse(prod)> response = TopicEmbed.find_remote(url)
discourse(prod)> puts “Remote fetch success: #{response.present?}”
discourse(prod)> puts “Remote body present: #{response&.body.present?}”
discourse(prod)> puts “Remote body length: #{response&.body&.length || 0}”
discourse(prod)> puts “Remote title: #{response&.title}”
discourse(prod)> puts “Remote body: #{response&.body&.truncate(500)}”
Remote fetch success: true
Remote body present: true
Remote body length: 3776
Remote title: Governo renova app da CNH para baratear obtenção do documento • Tecnoblog
Remote body: 

<figure><img src="https://files.tecnoblog.net/wp-content/uploads/2025/12/cnh-brasil-app-1060x596.jpg">

	<figcaption>Aplicativo CNH do Brasil (imagem: Emerson Alecrim/Tecnoblog)</figcaption></figure>

</div>

<details>
    Resumo
    <div><ul>
<li>App CNH do Brasil substitui CDT e passa a oferecer recursos para obtenção da CNH, em especial, aulas teóricas gratuitas;</li>
<li>Aulas práticas continuam obrigatórias, mas a carga horária mínima foi reduzida de ...
=> nil


Ici sans la barre oblique finale :

discourse(prod)> url = “https://tecnoblog.net/noticias/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento”
discourse(prod)> response = TopicEmbed.find_remote(url)
discourse(prod)> puts “Remote fetch success: #{response.present?}”
discourse(prod)> puts “Remote body present: #{response&.body.present?}”
discourse(prod)> puts “Remote body length: #{response&.body&.length || 0}”
discourse(prod)> puts “Remote title: #{response&.title}”
discourse(prod)> puts “Remote body: #{response&.body&.truncate(500)}”
Remote fetch success: true
Remote body present: true
Remote body length: 22
Remote title:
Remote body: 
=> nil

La même erreur se produit dans les anciens messages, où le slug du message a changé.

Par exemple, dans ce message, l’URL était :

https://tecnoblog.net/486925/o-que-e-pirataria-digital/

Maintenant, elle est devenue :

https://tecnoblog.net/responde/o-que-e-pirataria-digital/

1 « J'aime »

C’est le problème principal, semble-t-il. Lorsque vous utilisez Embed Discourse comments on another website via Javascript, vous contrôlez cela via un paramètre, c’est super facile à corriger.

Je ne sais pas comment WP-Discourse détermine cela, il devrait utiliser le canonique du message, mais je n’en suis pas sûr. Des idées @angus ?

Existe-t-il un moyen de forcer Discourse à mettre à jour toutes les URL d’intégration d’une catégorie, en la suivant jusqu’à la destination finale ?

J’ai l’intention de migrer vers l’intégration Discourse (cette intégration complète que vous avez testée) lorsqu’elle sera prête pour la production. Mais si les URL d’intégration ne correspondent pas, cela créera probablement de nouveaux sujets pour chaque publication et fera perdre les commentaires…

1 « J'aime »

Exécutez

te = TopicEmbed.find_by(topic_id: 157462)
te.embed_url = te.embed_url + "/"
te.save

Est-ce que cela corrige https://tecnoblog.net/comunidade/t/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento/157462 ?

Ça fonctionne !

Mais y a-t-il une solution pour des cas comme celui-ci ?

Gemini a suggéré ce code :

# Configuration
CATEGORY_SLUG = 'tb' 
category = Category.find_by(slug: CATEGORY_SLUG)

unless category
  puts "ERREUR : Catégorie '#{CATEGORY_SLUG}' non trouvée."
  exit
end

puts "Démarrage de l'analyse complète des URL dans la catégorie '#{category.name}'..."
puts "Cela peut prendre du temps en fonction du nombre de sujets et de la réponse de votre site..."

count_updated = 0
count_errors = 0
count_ok = 0

Topic.where(category_id: category.id).find_each do |topic|
  current_url = topic.custom_fields["embed_url"]
  
  # Sauter si embed_url n'est pas présent
  next unless current_url.present?

  begin
    # Effectuer la requête GET en suivant les redirections
    response = Faraday.get(current_url)
    final_url = response.env.url.to_s

    # Si la requête a réussi (200 OK)
    if response.status == 200
      # Vérifier si l'URL finale est différente de l'URL enregistrée dans la base de données
      # La comparaison ignore les différences subtiles si nécessaire, mais ici nous comparons la chaîne exacte
      if final_url != current_url
        puts "\n[MISE À JOUR] Sujet ##{topic.id} :"
        puts "   De:   #{current_url}"
        puts "   À: #{final_url}"
        
        topic.custom_fields["embed_url"] = final_url
        topic.save_custom_fields(true)
        count_updated += 1
      else
        # print "." # Décommentez pour voir la progression visuelle (points)
        count_ok += 1
      end
    else
      puts "\n[ERREUR HTTP #{response.status}] Sujet ##{topic.id} - URL : #{current_url}"
      count_errors += 1
    end

  rescue Faraday::ConnectionFailed, Faraday::TimeoutError => e
    puts "\n[ÉCHEC DE CONNEXION] Sujet ##{topic.id} - URL : #{current_url} - #{e.message}"
    count_errors += 1
  rescue StandardError => e
    puts "\n[ERREUR GÉNÉRALE] Sujet ##{topic.id} - #{e.message}"
    count_errors += 1
  end
  
  # Optionnel : Petite pause pour ne pas surcharger votre serveur WordPress
  # sleep 0.1 
end

puts "\n\nRésumé Final :"
puts "------------------------------------------------"
puts "Sujets Vérifiés (OK) : #{count_ok}"
puts "Sujets Mis à Jour :      #{count_updated}"
puts "Erreurs Rencontrées :        #{count_errors}"
puts "------------------------------------------------"

Enfin un peu de progrès :sweat_smile:

Un script comme celui-là est une excellente idée, mais faites une sauvegarde avant de l’exécuter.

Même une sauvegarde de cette petite table serait géniale.

1 « J'aime »

Ok ! J’essaierai de l’exécuter plus tard, lorsque l’équipe aura terminé son quart de travail.

1 « J'aime »

Salut à tous, je vois que la barre oblique de fin a encore frappé :slight_smile:

[les barres obliques de fin sont] le problème principal, semble-t-il. Lorsque vous utilisez Intégrer les commentaires Discourse sur un autre site via Javascript, vous contrôlez cela via un paramètre, c’est super facile à corriger.

Juste pour information, toutes les intégrations de sujets dans Discourse suppriment les barres obliques de fin de l’embed_url ; voir TopicEmbed.normalize_url. À la suite d’un cas distinct impliquant l’intersection des intégrations javascript et des intégrations WP Discourse, nous avons standardisé ce traitement sur les deux méthodes d’intégration. Voir Apply TopicEmbed url normalisation to embed urls inserted in the PostCreator by angusmcleod · Pull Request #30641 · discourse/discourse · GitHub

@Thiago_Mobilon Dans le cadre de cette évolution, avez-vous également mis à jour votre Discourse ? Il se peut que nous constations l’application de la standardisation de la normalisation de l’embed_url aux intégrations WP Discourse suite à une mise à jour de votre Discourse, qui a eu lieu en même temps que le passage à l’installation dans un sous-dossier. Quelle version de Discourse utilisez-vous actuellement ? (et quelle version utilisiez-vous avant le changement, si vous le savez ?)

Juste pour information, lorsque j’exécute ces deux commandes localement sur la dernière version de Discourse, j’obtiens le même résultat, à savoir le corps HTML de l’article

# avec barre oblique de fin
TopicEmbed.find_remote("https://tecnoblog.net/noticias/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento/")

# sans barre oblique de fin
TopicEmbed.find_remote("https://tecnoblog.net/noticias/governo-renova-app-da-cnh-para-baratear-obtencao-do-documento")

# produit le même résultat

Auriez-vous peut-être effectué un changement du côté de Wordpress ?

2 « J'aime »

Salut Angus !

Non, ce sont des problèmes différents. La barre oblique de fin a commencé lorsque nous sommes passés au sous-dossier, mais il y a aussi d’anciennes URL datant d’il y a des années qui ont maintenant un slug différent.

J’ai dû reconstruire l’installation, donc oui, je pense que ce nouveau standard pourrait en être la cause.

Ma suggestion pour résoudre ce problème : Discourse ne pourrait-il pas suivre au moins une ou deux redirections pour récupérer les données ? Cela résoudrait le problème de la barre oblique de fin et rendrait également le site Web à l’épreuve des balles en cas de changements d’URL futurs.

De plus, c’est plus sûr, car il ne serait pas nécessaire d’exécuter des scripts pour mettre à jour d’anciens sujets, ce qui pourrait également causer des dommages à la base de données.