Hallo! Ich möchte alle externen Links (oder falls eine Filterung nicht möglich ist, alle Links) auf z. B. exit.website.tld/?page={{URL}} umleiten. Ist das mit Discourse möglich? Falls nicht, gibt es dafür ein Plugin? Ich habe bereits gesucht, konnte aber mit meinen Suchbegriffen keines finden.
Ähnlich wie es Steam macht. (Beispiel)
Ich habe auch darüber nachgedacht; ich wollte die Internet-Archive-Save-URL an alle externen Links anhängen, und seien wir ehrlich: Es wäre cool, das nach Kategorie einzustellen.
Ich gehe davon aus, dass es dafür eine Filtermöglichkeit durch ein Plugin gibt, aber die Leute nutzen Theme-Komponenten auf eine Weise, die die Regeln für die Datenmanipulation zu umgehen scheint. Falls dies derzeit nicht möglich ist, wie würden Sie das angehen: über ein Plugin oder eine Theme-Komponente?
Wir betrachten dies als eine Art benutzerfeindliche Funktion (in der Art von „Foren-Signaturen“) und würden sie daher als Plugin umsetzen. Ob sie sich eventuell in einer Theme-Komponente realisieren ließe, bin ich mir nicht sicher.
Ich habe diese Anfrage bereits im Kontext der Sicherheit gesehen, und zwar so:
oh nein! Du bist dabei, einen HYPERLINK zu einer WEBSITE zu besuchen! Hast du dich auf die UNGLAUBLICHE GEFAHR vorbereitet?!??
Und ich vermute mal, dass das in einigen extrem seltenen Kontexten in einigen extrem seltenen Communities Sinn ergeben könnte … äh … ich glaube schon?
Ich leite eine Kategorie zum Archivieren von Websites. Unser Anwendungsfall ist super-spezifisch/faul. ![]()
Außerdem stelle ich mir den Web-Archive-Proxy ähnlich vor wie das Speichern einer Kopie eines Bildes in einer Nachricht, aber noch einmal: ich leite eine Kategorie zum Archivieren von Websites. ![]()
Meiner Meinung nach könnte es tatsächlich eine Sicherheitsangelegenheit sein, denn natürlich wissen hier auf dem Discourse-Meta-Forum oder auf einigen Programmierforen die Leute, wie man URLs unterscheidet usw., aber auf Foren, die nicht so sehr auf Technik ausgerichtet sind (insbesondere Foren für nicht-technische Berufe, Schulen usw.), merken viele Leute vielleicht nicht, wenn sie sich auf einer Seite befinden, die gleich aussieht, aber eine andere TLD hat oder sogar einen komplett anderen Domainnamen.
Und obwohl dies natürlich für einige Foren benutzerfeindlich sein mag, sagt niemand, dass es standardmäßig aktiviert sein muss. Man könnte es einfach wie ein Kontrollkästchen gestalten, das dann eine Seite von Discourse selbst verwendet oder direkt auf eine benutzerdefinierte Seite verlinkt.
Meiner Meinung nach ist dies eher eine wesentliche Funktion, die direkt in Discourse enthalten sein sollte, aber natürlich ist das nur meine eigene Meinung.
Jeff hat deutlich gemacht, dass dies ein Plugin sein muss (es sei denn, es kann in einem Theme umgesetzt werden, was wahrscheinlich ist). Die bisherigen Erfahrungen deuten darauf hin, dass, wenn Sie sich um die Entwicklung der Anmeldung kümmern und Hunderte von Websites dies wünschen – darunter Dutzende von Unternehmenskunden –, es innerhalb weniger Jahre zu einem offiziellen Plugin werden sollte.
Aber wenn es möglich ist, dies in einem Theme umzusetzen, was meiner Meinung nach der Fall sein könnte, dann unterstützt Discourse die Funktion bereits; Sie benötigen lediglich ein Theme dafür! Sie können den Entwicklerleitfaden für Discourse-Themes konsultieren oder im Marketplace mit einem Budget posten. Meine Schätzung liegt bei mindestens 1000 $, aber ich könnte auch falsch liegen.
Obwohl ich keine Erfahrung mit Discourse-Themes usw. habe, verfüge ich über grundlegende Kenntnisse in JS und HTML. Etwas wie das sollte nicht mehr als 10–20 Minuten Arbeit erfordern. Warum sollte dafür ein Budget von 1000 $ benötigt werden?
Wenn du es in zwanzig Minuten schaffen kannst, hättest du es bereits erledigt. Ich bin immer noch ziemlich schlecht in JavaScript und Ember; vielleicht ist es viel einfacher, als ich denke. Ich schätze, es sind mehrere Stunden Arbeit.
Bitte poste einen Link zu deinem Theme! Ich kann es kaum erwarten, es zu sehen.
Nach etwa 5 Minuten hatte ich funktionierenden JS-Code (der zwar noch einige Verbesserungen braucht, aber funktioniert; übrigens 10 Zeilen).
Das Einzige, was ich jetzt noch herausfinden muss, ist, wie man diesen Code nach dem Laden der Seite ausführt…
Toll! Schön, dass es so einfach war! Das nimmt mir normalerweise eine wahnsinnige Menge Zeit in Anspruch. Ich bin eigentlich besser darin zu schätzen, wie lange es eigentlich dauern sollte.
Im Allgemeinen wird lediglich geprüft, ob Sie sich auf einer Artikelseite befinden, durch alle <article>-Tags iteriert, das tatsächliche Tag mit dem Inhalt darin gefunden, durch alle darin enthaltenen <a>-Tags iteriert und falls deren href keine offizielle Seite ist (dafür wird eine einfache reguläre Expression verwendet), die Exit-Page-URL davor eingefügt.
Ich habe jedoch immer noch Schwierigkeiten herauszufinden, wie der JS-Code nachdem die Seite geladen wurde und alle dynamischen Inhalte (wie Beiträge) geladen sind, ausgeführt werden kann. Eine vorübergehende Lösung wäre, den Code einfach nach 1–2 Sekunden auszuführen, aber das ist nicht optimal, und für manche Nutzer könnte der Ladevorgang länger dauern…
Es kann definitiv als Theme-Komponente umgesetzt werden, aber beachte bitte, dass es ein Plugin sein muss, wenn es auch die Crawler-Ansicht beeinflussen soll.
Das, wonach du suchst, heißt Post-Decorator. Es ist ein Hook, der es ermöglicht, Skripte auszuführen, bevor jeder Beitrag gerendert wird. Es ist Teil der Plugin-API.
Was nun dein Vorhaben angeht (alle externen Links umzuleiten): Ich glaube nicht, dass so viel Reibung eine gute Idee ist, daher kann ich dir dabei nicht helfen – außerdem hast du diesen Teil schon selbst herausgefunden. Dennoch hier ein kommentiertes Beispiel, wie du eine Einrichtung erstellen kannst, die alle externen Links in Beiträgen anspricht.
Dies geht in den header-Bereich deines Themes bzw. Theme-Komponenten:
<script type="text/discourse-plugin" version="0.8">
// Speichere den Hostnamen, damit wir ihn wiederverwenden können.
const siteHostname = location.hostname;
// Erstellen wir einen Decorator, um dies in jedem Beitrag durchzuführen
api.decorateCooked(
post => {
// Enthält der Beitrag Links?
const links = [...post[0].querySelectorAll("a")];
// Keine Links vorhanden, abbrechen.
if (!links.length) return;
// Wir haben Links, filtern sie und holen nur die externen heraus
const externalLinks = links.filter(
link => link.hostname !== siteHostname
);
// Wenn wir externe Links haben, können wir etwas tun. Zum Beispiel können wir
// jeder externen Link eine Klasse hinzufügen, wie hier gezeigt.
externalLinks.forEach(link => {
link.classList.add('external-link');
// Hier können weitere Aktionen erfolgen.
});
},
// Wir geben unserem Decorator eine ID, um Speicherlecks zu vermeiden.
{ id: "external-link-decorator" }
);
</script>
Noch einmal: Benutzer umzuleiten erzeugt zu viel Reibung und wird schnell lästig. Daher würde ich einen anderen Ansatz in Betracht ziehen, zum Beispiel das Hinzufügen eines dezenten Icons neben externe Links und das Erläutern seiner Bedeutung für deine Nutzer?
Ich denke, dieser Anwendungsfall wird viel besser durch ein Plugin oder eine externe Integration (unter Verwendung eines Webhooks zum Erstellen/Bearbeiten von Beiträgen) bedient, die sicherstellt, dass alle verlinkten Websites ordnungsgemäß archiviert werden, unabhängig davon, ob jemand auf sie klickt oder nicht.

