Discourse enthält Hunderte von Plugin-Outlets, die verwendet werden können, um neuen Inhalt in die Discourse-Benutzeroberfläche einzufügen oder vorhandenen Inhalt zu ersetzen. „Outlet-Argumente“ werden zur Verfügung gestellt, damit Inhalte basierend auf dem Kontext angepasst werden können.
Ein Outlet auswählen
Um den Namen eines Plugin-Outlets zu finden, durchsuchen Sie den Discourse-Kern nach „\u003cPluginOutlet“ oder verwenden Sie die Theme-Komponente Plugin Outlet Locations. (z. B. topic-above-posts).
Wrapper-Outlets
Einige Outlets im Kern sehen so aus: \u003cPluginOutlet @name=\"foo\" /\u003e. Diese ermöglichen es Ihnen, neuen Inhalt einzufügen. Andere Outlets „umschließen“ eine vorhandene Kernimplementierung wie folgt:
\u003cPluginOutlet @name=\"foo\"\u003e
Kernimplementierung
\u003c/PluginOutlet\u003e
Die Definition eines Connectors für diese Art von „Wrapper“-Outlet ersetzt die Kernimplementierung. Nur ein aktives Theme/Plugin kann einen Connector für ein Wrapper-Plugin-Outlet bereitstellen.
Bei Wrapper-Plugin-Outlets können Sie die ursprüngliche Kernimplementierung mit dem Schlüsselwort {{yield}} rendern. Dies kann hilfreich sein, wenn Sie die Kernimplementierung nur unter bestimmten Bedingungen ersetzen möchten oder wenn Sie sie in etwas einbetten möchten.
Die Vorlage definieren
Sobald Sie ein Outlet ausgewählt haben, entscheiden Sie sich für einen Namen für Ihren Connector. Dieser muss eindeutig für alle auf einer bestimmten Community installierten Themes/Plugins sein. Z. B. brand-official-topics
Definieren Sie in Ihrem Theme/Plugin eine neue Handlebars-Vorlage mit einem Pfad, der wie folgt formatiert ist:
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.hbs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.hbs
Der Inhalt dieser Dateien wird als Ember Component gerendert. Allgemeine Informationen zu Ember/Handlebars finden Sie in den Ember-Anleitungen.
Für unseren hypothetischen „brand official topics“-Connector könnte die Vorlage wie folgt aussehen:
\u003cdiv class=\"alert alert-info\"\u003e
Dieses Thema wurde von einem Mitglied des
\u003ca href=\"https://discourse.org/team\"\u003eDiscourse Teams\u003c/a\u003e
erstellt
\u003c/div\u003e
Einige Plugin-Outlets umschließen Ihren Inhalt automatisch in einem HTML-Element. Der Elementtyp wird durch @connectorTagName auf dem \u003cPluginOutlet\u003e definiert.
Outlet-Argumente verwenden
Plugin-Outlets stellen Informationen über den umgebenden Kontext über @outletArgs bereit. Die an jedes Outlet übergebenen Argumente variieren. Eine einfache Möglichkeit, die Argumente anzuzeigen, besteht darin, dies zu Ihrer Vorlage hinzuzufügen:
{{log @outletArgs}}
Dies protokolliert die Argumente in der Entwicklerkonsole Ihres Browsers. Sie erscheinen als Proxy-Objekt – um die Liste der Argumente zu untersuchen, 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:
\u003cdiv class=\"alert alert-info\"\u003e
Dieses Thema wurde erstellt von
{{@outletArgs.model.details.created_by.username}}
(ein Mitglied des
\u003ca href=\"https://discourse.org/team\"\u003eDiscourse Teams\u003c/a\u003e)
\u003c/div\u003e
Komplexere Logik hinzufügen
Manchmal reicht eine einfache Handlebars-Vorlage nicht aus. Um Ihrer Connector-Logik Javascript hinzuzufügen, können Sie eine Javascript-Datei neben Ihrer Handlebars-Vorlage definieren. Diese Datei sollte eine Komponenten-Definition exportieren. Dies funktioniert genauso wie jede andere Komponenten-Definition und kann Service-Injektionen enthalten.
Die Definition einer Komponente auf diese Weise entfernt das automatische connectorTagName-Wrapper-Element, sodass Sie möglicherweise ein Element desselben Typs in Ihrer hbs-Datei wieder einführen möchten.
In unserem topic-above-posts-Beispiel möchten wir den Benutzer möglicherweise anders rendern, basierend auf der Site-Einstellung „Benutzernamen in der UX priorisieren“. Eine Komponenten-Definition dafür könnte etwa so aussehen:
.../connectors/topic-above-posts/brand-official-topic.js:
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;
}
}
}
Wir können dann die Vorlage aktualisieren, um auf den neuen Getter zu verweisen:
\u003cdiv class=\"alert alert-info\"\u003e
Dieses Thema wurde erstellt von
{{this.displayName}}
(ein Mitglied des
\u003ca href=\"https://discourse.org/team\"\u003eDiscourse Teams\u003c/a\u003e)
\u003c/div\u003e
Bedingtes Rendern
Wenn Sie möchten, dass Ihr Inhalt nur unter bestimmten Bedingungen gerendert wird, reicht es oft aus, Ihre Vorlage mit einem Handlebars {{#if}}-Block zu umschließen. Wenn das nicht ausreicht, möchten Sie möglicherweise den Hook shouldRender verwenden, um zu steuern, ob Ihre Connector-Vorlage überhaupt gerendert wird.
Stellen Sie zunächst sicher, dass Sie eine .js-Connector-Definition wie oben beschrieben haben. Fügen Sie dann eine statische Funktion shouldRender() hinzu. Erweiterung unseres Beispiels:
import Component from "@glimmer/component";
import { getOwner } from "discourse-common/lib/get-owner";
export default class BrandOfficialTopics extends Component {
static shouldRender(outletArgs, helper) {
const firstPost = outletArgs.model.postStream.posts[0];
return firstPost.primary_group_name === "team";
}
// ... (jede andere Logik)
}
Nun 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 allen referenzierten Eigenschaften (z. B. outletArgs) führen dazu, dass die Funktion neu ausgewertet wird.
Neue Outlets einführen
Wenn Sie ein Outlet benötigen, das noch nicht existiert, können Sie gerne eine Pull-Anfrage stellen oder ein Thema in Dev eröffnen.
\u003csmall\u003eDieses Dokument wird versionskontrolliert – schlagen Sie Änderungen auf github vor.\u003c/small\u003e