Quando si tenta di implementare [1] nella propria Single Page Application (SPA) che non fornisce pagine renderizzate lato server, si finirà per incontrare problemi, vedere: [2]
Quindi, dopo un po’ di sperimentazione, vorrei presentare il seguente approccio. L’esempio è in Vue.js, tuttavia, può essere facilmente adattato ad altri framework/librerie.
Nota: Utilizzerò il termine articoli del blog dove dovrebbe essere incorporata una sezione di commenti di Discourse. Ma ovviamente questo può significare anche singole pagine del tuo sito.
1. I problemi in [1]
1.1. javascripts/embed.js non può funzionare con contenuti renderizzati lato client
Lo snippet <script>...</script> che ti viene detto in [1] di inserire nel tuo HTML, quindi, non farà parte dell’implementazione che stiamo affrontando qui. Utilizzeremo alcune parti di javascripts/embed.js fornite dalla tua istanza di Discourse come funzioni all’interno della nostra SPA.
1.2. Discourse non può fare lo scraping di contenuti renderizzati lato client
Discourse crea automaticamente argomenti per ogni articolo del blog e tenta di accedere all’URL originale (di un articolo del blog) per determinare il titolo e il contenuto. Questo fallisce con una SPA, perché Discourse otterrà la parte non-javascript di essa, ad esempio Siamo spiacenti ma questo sito non funziona correttamente senza JavaScript abilitato. Abilitalo per continuare.
Utilizzeremo il plugin RSS Polling per fornire i dati necessari e creare gli argomenti per noi.
2. L’implementazione
2.1 RSS Polling e il feed RSS/Atom
Crea un endpoint sul tuo sito che fornisca un feed RSS o Atom per il plugin RSS Polling. Questo endpoint può essere solo un file statico formattato XML o una funzione lato server che fornisce il contenuto formattato XML, esempio:
URL: https://mysite.com/blog.atom
Contenuto:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Articoli del Blog del Mio Sito</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 Articolo sulla Tecnologia</title>
<author>
<name>Il Tuo Nome Qui</name>
</author>
<link href="https://mysite.com/blog/un-articolo-sulla-tecnologia"/>
<id>urn:uuid:f6cc13e4-d2eb-4385-af28-c867a94f48dc</id>
<published>2022-07-03T00:00:00Z</published>
<updated>2022-07-03T00:00:00Z</updated>
<summary>Discutiamo un po' di tecnologia in questo articolo.</summary>
</entry>
</feed>
Installa il plugin RSS Polling per Discourse come descritto in [3] (Discourse ospitato) o [4] (ospitato autonomamente)
Impostazioni consigliate per RSS Polling in Admin → Impostazioni → Plugin:
| Chiave | Valore |
|---|---|
| rss polling enabled | true |
| rss polling frequency | 10 (cioè 10 minuti) |
Aggiungi un nuovo feed nella configurazione del plugin RSS Polling in Admin → Plugin → RSS Polling
Configuralo come descritto in [3]:
| Chiave | Valore |
|---|---|
| URL | https://mysite.com/blog.atom |
| Category Filter | <questo è opzionale> |
| Author | <definisci un autore degli argomenti generati automaticamente> |
| Category | <definisci la/le categoria/e dove verranno pubblicati gli argomenti generati automaticamente> |
| Tags | <questo è opzionale> |
2.2 Configurazione del Router SPA
Discourse utilizza l’ultima parte del percorso dell’URL come identificatore per un singolo articolo del blog.
Esempi:
https://mysite.com/blog/un-articolo-sulla-tecnologia
https://mysite.com/blog/un-altro-articolo-sui-gatti
Configura il tuo router SPA di conseguenza, in modo che i singoli articoli del blog corrispondano a URL individuali.
Inoltre: Discourse fornirà un link all’articolo del blog individuale, quindi è una buona UX che quando cliccato, il tuo sito mostri l’articolo effettivo.
2.3 Il Componente Articolo
Come detto prima, non possiamo usare l’approccio con lo <script></script> di [1]. Quindi implementiamo l’iframe e alcune funzioni da javascripts/embed.js nel nostro componente:
Article.vue
Cose da modificare:
| Elemento | Descrizione |
|---|---|
| #YOUR-DISCOURSE-URL# | l’URL della tua istanza di Discourse, ad es. discourse.mysite.com) |
| #YOUR-SITE-URL# | l’URL del tuo sito, ad es. mysite.com eventualmente anche %2Fblog%2F se il percorso dei tuoi articoli non è /blog/ |
<template>
<div id="article">
<!-- il tuo articolo formattato qui -->
<iframe
v-if="slug"
v-bind:src="`https://#YOUR-DISCOURSE-URL#/embed/comments?embed_url=https%3A%2F%2F#YOUR-SITE-URL#%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, // lo slug dell'articolo del blog, ad es. "un-articolo-sulla-tecnologia" mentre il percorso è "https://mysite.com/blog/un-articolo-sulla-tecnologia"
iframeHeight: 0 // Discourse ci dirà l'altezza esatta dell'iframe (vedi: metodo receiveMessage)
}),
methods: {
// comunicazione iframe
receiveMessage(event) {
if (!event) {
return;
}
if (!(event.origin || "").includes("#YOUR-DISCOURSE-URL#")) {
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) {
// trova l'offset dell'iframe
const destY = this.findPosY(this.$refs["discourse-embed-frame"]) + event.data.top;
window.scrollTo(0, destY);
}
}
},
// Grazie a 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 Configurazione Embed Discourse
Ora con il polling del feed RSS/Atom attivo e l’implementazione sul tuo sito, possiamo finalmente configurare l’embedding sull’istanza di Discourse.
Vai su Admin → Personalizza → Embedding e aggiungi un host:
| Chiave | Valore |
|---|---|
| Allowed Hosts | il tuo URL base del sito> es. “mysite.com” |
| Class Name | nome classe opzionale per lo styling |
| Path Allowlist | es. “/blog/.*” |
| Post to Category | la stessa categoria configurata in RSS Polling Category |
3. Note Finali
Il polling del feed RSS/Atom e Discourse stesso creeranno un nuovo argomento se non esiste per il singolo articolo del blog. Assicurati che il polling del feed RSS/Atom avvenga per primo (cioè, attendi che l’argomento venga creato prima di visitare l’articolo del blog sul tuo sito).
Motivo: Discourse non può fare lo scraping del titolo e del riassunto, quindi l’argomento sarebbe mysite.com con il riassunto Siamo spiacenti, ma questo sito non funziona senza javascript. ![]()
Se per qualche motivo Discourse venisse prima, puoi semplicemente eliminare l’argomento e attendere che il feed RSS/Atom venga elaborato.
Saluti
– MK2k