Lorsque vous essayez d’implémenter [1] dans votre application monopage (SPA) qui ne fournit pas de pages rendues côté serveur, vous rencontrerez des problèmes, voir : [2]
Après quelques expérimentations, j’aimerais vous présenter l’approche suivante. L’exemple est en Vue.js, mais il peut être facilement adapté à d’autres frameworks/bibliothèques.
Remarque : J’utiliserai le terme articles de blog là où une section de commentaires Discourse devrait être intégrée. Mais cela peut bien sûr aussi signifier des pages individuelles sur votre site.
1. Les problèmes de [1]
1.1. javascripts/embed.js ne peut pas fonctionner avec du contenu rendu côté client
L’extrait \u003cscript\u003e...\u003c/script\u003e que l’on vous dit dans [1] d’insérer dans votre HTML ne fera donc pas partie de l’implémentation que nous abordons ici. Nous utiliserons certains éléments de javascripts/embed.js fournis par votre instance Discourse comme fonctions au sein de notre SPA.
1.2. Discourse ne peut pas analyser le contenu rendu côté client
Discourse crée automatiquement des sujets pour chaque article de blog et essaie d’accéder à l’URL d’origine (d’un article de blog) pour déterminer le titre et le contenu. Cela échoue avec une SPA, car Discourse obtiendra la partie sans JavaScript, par exemple Nous sommes désolés mais ce site ne fonctionne pas correctement sans JavaScript activé. Veuillez l'activer pour continuer.
Nous utiliserons le plugin RSS Polling pour fournir les données nécessaires et créer les sujets pour nous.
2. L’implémentation
2.1 RSS Polling et le flux RSS/Atom
Créez un point de terminaison sur votre site qui fournit un flux RSS ou Atom pour le plugin RSS Polling. Ce point de terminaison peut être soit un fichier statique formaté en XML, soit une fonction côté serveur fournissant le contenu formaté en XML, exemple :
URL : https://mysite.com/blog.atom
Contenu :
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Articles de blog de Mon Site</title>
<link href="https://mysite.com/blog/"/>
<updated>2022-07-03T09:02:48.721Z</updated>
<id>urn:uuid:790c1857-b968-49cc-9fbd-bf7afe3552c2</id>
<entry>
<title>Un article sur la technologie</title>
<author>
<name>Votre Nom Ici</name>
</author>
<link href="https://mysite.com/blog/un-article-sur-la-technologie"/>
<id>urn:uuid:f6cc13e4-d2eb-4385-af28-c867a94f48dc</id>
<published>2022-07-03T00:00:00Z</published>
<updated>2022-07-03T00:00:00Z</updated>
<summary>Discutons de technologie dans cet article.</summary>
</entry>
</feed>
Installez le plugin RSS Polling pour Discourse conformément à [3] (Discourse hébergé) ou [4] (auto-hébergé)
Paramètres recommandés pour RSS Polling dans Admin → Paramètres → Plugins :
| Clé | Valeur |
|---|---|
| rss polling enabled | true |
| rss polling frequency | 10 (soit 10 minutes) |
Ajoutez un nouveau flux dans la configuration du plugin RSS Polling à Admin → Plugins → RSS Polling
Configurez-le conformément à [3] :
| Clé | Valeur |
|---|---|
| URL | https://mysite.com/blog.atom |
| Filtre de catégorie | \u003cceci est optionnel\u003e |
| Auteur | \u003cDéfinir un auteur pour les sujets générés automatiquement\u003e |
| Catégorie | \u003cDéfinir la/les catégorie(s) où les sujets générés automatiquement seront publiés\u003e |
| Tags | \u003cceci est optionnel\u003e |
2.2 Configuration du routeur SPA
Discourse utilise la dernière partie du chemin d’URL comme identifiant pour un article de blog individuel.
Exemples :
https://mysite.com/blog/un-article-sur-la-technologie
https://mysite.com/blog/un-autre-article-sur-les-chats
Configurez votre routeur SPA en conséquence, de sorte que les articles de blog individuels correspondent à des URL individuelles.
Aussi : Discourse fournira un lien de retour vers l’article de blog individuel, il est donc bon pour l’expérience utilisateur que lorsque vous cliquez dessus, votre site affiche l’article réel.
2.3 Le composant Article
Comme indiqué précédemment, nous ne pouvons pas utiliser l’approche avec le \u003cscript\u003e\u003c/script\u003e de [1]. Nous implémentons donc l’iframe et certaines fonctions de javascripts/embed.js dans notre composant :
Article.vue
Choses que vous devriez modifier :
| Élément | Description |
|---|---|
| #VOTRE-URL-DISCOURSE# | l’URL de votre instance Discourse, par exemple discourse.mysite.com) |
| #VOTRE-URL-SITE# | l’URL de votre site, par exemple mysite.com éventuellement aussi %2Fblog%2F si le chemin de vos articles de blog n’est pas /blog/ |
<template>
<div id="article">
<!-- votre article formaté ici -->
<iframe
v-if="slug"
v-bind:src="`https://#VOTRE-URL-DISCOURSE#/embed/comments?embed_url=https%3A%2F%2F#VOTRE-URL-SITE#%2Fblog%2F${slug}%2F`"
id="discourse-embed-frame"
width="100%"
v-bind:height="`${iframeHeight}px`"
frameborder="0"
scrolling="no"
referrerpolicy="no-referrer-when-downgrade"
/>
</div>
</template>
<script>
export default {
data: () => ({
slug: null, // le slug de l'article de blog, par exemple "un-article-sur-la-technologie" alors que la route est "https://mysite.com/blog/un-article-sur-la-technologie"
iframeHeight: 0 // Discourse nous indiquera la hauteur exacte de l'iframe (voir : méthode receiveMessage)
}),
methods: {
// communication iframe
receiveMessage(event) {
if (!event) {
return;
}
if (!(event.origin || "").includes("#VOTRE-URL-DISCOURSE#")) {
return;
}
if (event.data) {
if (event.data.type === "discourse-resize" && event.data.height) {
this.iframeHeight = +event.data.height;
}
if (event.data.type === "discourse-scroll" && event.data.top) {
// trouver le décalage de l'iframe
const destY = this.findPosY(this.$refs["discourse-embed-frame"]) + event.data.top;
window.scrollTo(0, destY);
}
}
},
// Merci http://amendsoft-javascript.blogspot.ca/2010/04/find-x-and-y-coordinate-of-html-control.html
findPosY(obj) {
var top = 0;
if (obj.offsetParent) {
while (1) {
top += obj.offsetTop;
if (!obj.offsetParent) break;
obj = obj.offsetParent;
}
} else if (obj.y) {
top += obj.y;
}
return top;
}
},
async created() {
this.slug = this.$router.currentRoute.path.split("/")[2];
},
mounted() {
window.addEventListener("message", this.receiveMessage);
},
beforeDestroy() {
window.removeEventListener("message", this.receiveMessage);
}
}
</script>
2.4 Configuration de l’intégration Discourse
Maintenant que le polling du flux RSS/Atom est en place et l’implémentation sur votre site, nous pouvons enfin configurer l’intégration sur l’instance Discourse.
Allez dans Admin → Personnaliser → Intégration et ajoutez un hôte :
| Clé | Valeur |
|---|---|
| Hôtes autorisés | votre URL de base de site\u003e par exemple “mysite.com” |
| Nom de classe | nom de classe optionnel pour le style |
| Liste d’autorisation de chemin | par exemple “/blog/.*” |
| Publier dans la catégorie | même catégorie que celle configurée dans la catégorie RSS Polling |
3. Remarques finales
Le polling du flux RSS/Atom ainsi que Discourse lui-même créeront un nouveau sujet s’il n’existe pas pour l’article de blog individuel. Assurez-vous que le polling du flux RSS/Atom se fasse en premier (c’est-à-dire attendez que le sujet soit créé avant de visiter l’article de blog sur votre site).
Raison : Discourse ne peut pas analyser le titre et le résumé, donc le sujet serait mysite.com avec le résumé étant Nous sommes désolés, mais ce site ne fonctionne pas sans JavaScript. ![]()
Si pour une raison quelconque Discourse est arrivé en premier, vous pouvez simplement supprimer le sujet et attendre que le flux RSS/Atom soit pris en compte.
Cordialement
– MK2k