Discourse enthält Hunderte von Plugin-Ausgängen (Plugin Outlets), die verwendet werden können, um neue Inhalte einzufügen oder vorhandene Inhalte in der Discourse-Benutzeroberfläche zu ersetzen. „Outlet-Argumente“ werden bereitgestellt, sodass Inhalte basierend auf dem Kontext angepasst werden können.
Einen Ausgang auswählen
Um den Namen eines Plugin-Ausgangs zu finden, suchen Sie im Discourse-Core nach “<PluginOutlet” oder verwenden Sie das Theme-Component Plugin-Ausgangsstandorte. (z. B. topic-above-posts).
Wrapper-Ausgänge
Einige Ausgänge im Core sehen wie <PluginOutlet @name="foo" /> aus. Diese ermöglichen es Ihnen, neue Inhalte einzufügen. Andere Ausgänge „umhüllen“ eine vorhandene Core-Implementierung, wie hier gezeigt:
<PluginOutlet @name="foo">
Core-Implementierung
</PluginOutlet>
Das Definieren eines Connectors für diese Art von „Wrapper“-Ausgang ersetzt die Core-Implementierung. Nur ein aktives Theme/Plugin kann einen Connector für einen Wrapper-Plugin-Ausgang bereitstellen.
Für Wrapper-Plugin-Ausgänge können Sie die ursprüngliche Core-Implementierung mit dem Schlüsselwort {{yield}} rendern. Dies kann hilfreich sein, wenn Sie die Core-Implementierung nur unter bestimmten Bedingungen ersetzen möchten oder wenn Sie sie in etwas einbetten möchten.
Den Connector definieren
Sobald Sie einen Ausgang gewählt haben, entscheiden Sie sich für einen Namen für Ihren Connector. Dieser muss in allen auf einer bestimmten Community installierten Themes/Plugins eindeutig sein, z. B. brand-official-topics.
Definieren Sie in Ihrem Theme/Plugin einen neuen .gjs-Connector mit einem Pfad, der wie folgt formatiert ist:
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
Der Inhalt dieser Dateien wird als Ember-Komponente gerendert. Für allgemeine Informationen zu Ember und dem .gjs-Format schauen Sie sich die Ember-Anleitungen an.
Für unseren hypothetischen „brand official topics“-Connector könnte die Datei so aussehen:
<template>
<div class="alert alert-info">
Dieses Thema wurde von einem Mitglied des
<a href="https://discourse.org/team">Discourse-Teams</a>
erstellt
</div>
</template>
Verwendung von Ausgangsargumenten
Plugin-Ausgänge liefern Informationen über den umgebenden Kontext über @outletArgs. Die an jeden Ausgang übergebenen Argumente variieren. Eine einfache Möglichkeit, die Argumente anzuzeigen, besteht darin, dies zu Ihrem Template hinzuzufügen:
{{log @outletArgs}}
Dies protokolliert die Argumente in der Entwicklerkonsole Ihres Browsers. Sie erscheinen als Proxy-Objekt – um die Liste der Argumente zu erkunden, erweitern Sie das [[Target]] des Proxys.
In unserem topic-above-posts-Beispiel ist das gerenderte Thema unter @outletArgs.model verfügbar. Wir können also den Benutzernamen des Teammitglieds wie folgt hinzufügen:
<template>
<div class="alert alert-info">
Dieses Thema wurde von
{{@outletArgs.model.details.created_by.username}}
(einem Mitglied des
<a href="https://discourse.org/team">Discourse-Teams</a>)
erstellt
</div>
</template>
Hinzufügen komplexerer Logik
Manchmal reicht ein einfaches Template nicht aus. Um Javascript-Logik zu Ihrem Connector hinzuzufügen, aktualisieren Sie Ihre .gjs-Datei, um eine klassenbasierte Komponente zu exportieren. Dies funktioniert genau wie jede andere Komponenten-Definition und kann Service-Injektionen enthalten.
In unserem topic-above-posts-Beispiel möchten wir den Benutzer möglicherweise basierend auf der Site-Einstellung „Priorität des Benutzernamens in UX“ unterschiedlich rendern. Die .gjs-Datei könnte so aussehen:
.../connectors/topic-above-posts/brand-official-topic.gjs:
import Component from "@glimmer/component";
import { service } from "@ember/service";
export default class BrandOfficialTopics extends Component {
@service siteSettings;
get displayName() {
const user = this.args.outletArgs.model.details.created_by;
if (this.siteSettings.prioritize_username_in_ux) {
return user.username;
} else {
return user.name;
}
}
<template>
<div class="alert alert-info">
Dieses Thema wurde von
{{this.displayName}}
(einem Mitglied des
<a href="https://discourse.org/team">Discourse-Teams</a>)
erstellt
</div>
</template>
}
Bedingtes Rendern
Wenn Sie möchten, dass Ihre Inhalte nur unter bestimmten Bedingungen gerendert werden, reicht es oft aus, Ihr Template mit einem Handlebars-{{#if}}-Block zu umschließen. Wenn das nicht ausreicht, können Sie den shouldRender-Hook verwenden, um zu steuern, ob Ihr Connector-Template überhaupt gerendert wird.
Stellen Sie zunächst sicher, dass Sie einen klassenbasierten .gjs-Connector haben, wie oben beschrieben. Fügen Sie dann eine static shouldRender()-Funktion hinzu. Erweiterung unseres Beispiels:
import Component from "@glimmer/component";
export default class BrandOfficialTopics extends Component {
static shouldRender(outletArgs, helper) {
const firstPost = outletArgs.model.postStream.posts[0];
return firstPost.primary_group_name === "team";
}
// ... (andere Logik)
<template>
{{! ... }}
</template>
}
Jetzt wird der Connector nur gerendert, wenn der erste Beitrag des Themas von einem Teammitglied erstellt wurde.
shouldRender wird in einem Glimmer-Autotracking-Kontext ausgewertet. Zukünftige Änderungen an beliebigen referenzierten Eigenschaften (z. B. outletArgs) führen dazu, dass die Funktion erneut ausgewertet wird.
Einführung neuer Ausgänge
Wenn Sie einen Ausgang benötigen, der noch nicht existiert, können Sie gerne einen Pull-Request erstellen oder ein Thema in Development eröffnen.
Dieses Dokument ist versioniert – schlagen Sie Änderungen auf GitHub vor.