Discourse ist eine Single-Page-Anwendung. Das Problem, auf das du stößt, tritt auf, weil das von dir verwendete Skript dies nicht berücksichtigt. Wenn du die Startseite oder eine beliebige andere Seite in Discourse besuchst, erhältst du etwas wie dies:
<html>
<head>
Head-Inhalte einschließlich deines Skripts
</head>
<body>
<section id="main">
Seiteninhalt
</section>
</body>
</html>
Wenn du zu einer anderen Seite navigierst, wird nur der Inhalt innerhalb von
<section id="main">
neu geladen.
Das DOM hat sich also geändert, und dein benutzerdefiniertes Skript wird nicht erneut ausgeführt. Wenn du versuchst, die Themen-Seite direkt aufzurufen, wirst du sehen, dass sie ordnungsgemäß lädt.
.Die Frage ist nun also, wie man dies mit Discourse zum Laufen bringt.
Die Plugin-API bietet eine Methode, mit der du Beiträge „dekoriert" kannst.
Damit kannst du Skripte von Drittanbietern ausführen, wenn ein Beitrag gerendert wird.
Hier ist der Code, den du benötigst. Füge dies im Reiter common > header deines Themes hinzu.
<script type="text/discourse-plugin" version="0.8">
const WOXO_SCRIPT_SRC = "https://cdn2.woxo.tech/a.js#616348fb53c1e8001686c619";
const PREVIEW_ICON = "heart";
const loadScript = require("discourse/lib/load-script").default;
const { iconHTML } = require("discourse-common/lib/icon-library");
const composerPreviewIcon = iconHTML(PREVIEW_ICON, {
class: "woxo-preview-icon"
});
const previewMarkup = () => {
const markup = `<div class="woxo-preview">${composerPreviewIcon}</div>`;
return markup;
};
// Erstelle einen Beitrags-Dekorator
api.decorateCookedElement(
post => {
const woxoWidgets = post.querySelectorAll("div[data-mc-src]");
if (woxoWidgets.length) {
woxoWidgets.forEach(woxoWidget => {
if (post.classList.contains("d-editor-preview")) {
woxoWidget.innerHTML = previewMarkup();
return;
}
loadScript(WOXO_SCRIPT_SRC).then(() => {
const script = document.head.querySelector(
`script[src*="cdn2.woxo.tech"]`
);
script.dataset.usrc = "";
window.MC.Loader.init();
});
});
}
},
{ id: "render-woxo-widgets" }
);
</script>
Anschließend musst du ein paar Domains für CSP hinzufügen. Füge diese zu deiner
content_security_policy_script_src
Site-Einstellung hinzu
https://*.woxo.tech/
https://us-central1-core-period-259421.cloudfunctions.net/availableComponentTracks
Schließlich musst du ein wenig CSS für die statische Composer-Vorschau hinzufügen.
Dies geht im Reiter common > CSS deines Themes.
.woxo-preview {
height: 400px;
width: 100%;
background: var(--primary-low);
display: flex;
align-items: center;
justify-content: center;
.woxo-preview-icon {
font-size: var(--font-up-4);
color: var(--primary-high);
}
}
Dann kannst du einfach
<div data-mc-src="f4b43a8f-c188-4f80-8206-36d9f7529f13#instagram"></div>
zu einem beliebigen Beitrag hinzufügen, und die Widgets werden gerendert und sind voll funktionsfähig.
Wenn du dir das JavaScript ansiehst, wirst du feststellen, dass es ganz oben zwei Optionen hat.
const WOXO_SCRIPT_SRC = "https://cdn2.woxo.tech/a.js#616348fb53c1e8001686c619";
const PREVIEW_ICON = "heart";
Ändere WOXO_SCRIPT_SRC in die Quelle, die dir Woxo gibt. Diese sollte für alle von dir erstellten Embeds gleich sein.
Ändere PREVIEW_ICON in den Namen des Icons, das du in der Composer-Vorschau verwenden möchtest. Die Ausführung dieses Codes im Composer ist etwas aufwendig, daher verfügt der Composer über eine statische Vorschau, die so aussieht:
Das von dir gewählte Icon wird in der Mitte angezeigt.
Hier ist eine kommentierte Version des Codes, falls du Schritt für Schritt mitgehen möchtest:
kommentierter Code
<script type="text/discourse-plugin" version="0.8">
// Optionen
const WOXO_SCRIPT_SRC = "https://cdn2.woxo.tech/a.js#616348fb53c1e8001686c619";
const PREVIEW_ICON = "heart";
// Wir verwenden die Discourse Load-Script-Bibliothek, um sicherzustellen, dass Skripte ordnungsgemäß geladen werden.
// Keine Sorge, dies ist intelligent genug, um das Skript nicht zu duplizieren, falls es bereits geladen ist.
const loadScript = require("discourse/lib/load-script").default;
// Wir laden die Discourse Icon-HTML-Funktion, um das SVG für das Icon zu erhalten,
// das wir in der statischen Composer-Vorschau verwenden möchten.
const { iconHTML } = require("discourse-common/lib/icon-library");
// Richte das Composer-Vorschau-Icon ein
const composerPreviewIcon = iconHTML(PREVIEW_ICON, {
class: "woxo-preview-icon"
});
// Erstelle eine Hilfsfunktion für die Composer-Vorschau-Markup
const previewMarkup = () => {
const markup = `<div class="woxo-preview">${composerPreviewIcon}</div>`;
return markup;
};
// Erstelle einen Beitrags-Dekorator
api.decorateCookedElement(
post => {
// Enthält dieser Beitrag Woxo-Widgets?
const woxoWidgets = post.querySelectorAll("div[data-mc-src]");
// Ja, also machen wir etwas.
if (woxoWidgets.length) {
// Für jedes Woxo-Widget
woxoWidgets.forEach(woxoWidget => {
// Wenn es sich um ein Composer-Widget handelt, ersetze es durch eine statische Vorschau und
// beende frühzeitig
if (post.classList.contains("d-editor-preview")) {
woxoWidget.innerHTML = previewMarkup();
return;
}
// Wenn es sich nicht um den Composer handelt, lade das Woxo-Skript.
loadScript(WOXO_SCRIPT_SRC).then(() => {
// Das Woxo-Skript ist sehr seltsam. Es funktioniert nicht, es sei denn, das Skript-Tag
// hat ein leeres data-usrc-Attribut. Also fügen wir es hinzu.
const script = document.head.querySelector(
`script[src*="cdn2.woxo.tech"]`
);
script.dataset.usrc = "";
// Alles ist bereit, rufen wir die init-Methode im Woxo-Skript auf.
window.MC.Loader.init();
});
});
}
},
// Füge eine ID zum Dekorator hinzu, um Speicherlecks zu vermeiden
{ id: "render-woxo-widgets" }
);
</script>


