Discourse inclut des centaines de Plugin Outlets (sorties de plugin) qui peuvent être utilisées pour injecter du nouveau contenu ou remplacer du contenu existant dans l’interface utilisateur de Discourse. Des « arguments d’outlet » sont mis à disposition afin de personnaliser le contenu en fonction du contexte.
Choisir un outlet
Pour trouver le nom d’un plugin outlet, recherchez « <PluginOutlet » dans le noyau de Discourse, ou utilisez le composant de thème plugin outlet locations. (par exemple topic-above-posts).
Outlets de type « wrapper »
Certains outlets dans le noyau ressemblent à <PluginOutlet @name="foo" />. Ceux-ci vous permettent d’injecter du nouveau contenu. D’autres outlets « enveloppent » une implémentation existante du noyau de cette manière :
<PluginOutlet @name="foo">
implémentation du noyau
</PluginOutlet>
Définir un connecteur pour ce type d’outlet de type « wrapper » remplacera l’implémentation du noyau. Un seul thème/plugin actif peut contribuer un connecteur pour un plugin outlet de type wrapper.
Pour les plugin outlets de type wrapper, vous pouvez rendre l’implémentation originale du noyau en utilisant le mot-clé {{yield}}. Cela peut être utile si vous ne souhaitez remplacer l’implémentation du noyau que sous certaines conditions, ou si vous souhaitez l’envelopper dans autre chose.
Définir le connecteur
Une fois que vous avez choisi un outlet, décidez d’un nom pour votre connecteur. Celui-ci doit être unique parmi tous les thèmes/plugins installés sur une communauté donnée. Par exemple : brand-official-topics.
Dans votre thème/plugin, définissez un nouveau connecteur .gjs avec un chemin formaté comme suit :
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
Le contenu de ces fichiers sera rendu sous forme de composant Ember. Pour des informations générales sur Ember et le format .gjs, consultez les guides Ember.
Pour notre connecteur hypothétique « brand official topics », le fichier pourrait ressembler à ceci :
<template>
<div class="alert alert-info">
Ce sujet a été créé par un membre de l'
<a href="https://discourse.org/team">Équipe Discourse</a>
</div>
</template>
Utiliser les arguments d’outlet
Les Plugin Outlets fournissent des informations sur le contexte environnant via @outletArgs. Les arguments passés à chaque outlet varient. Un moyen simple de visualiser les arguments est d’ajouter ceci à votre template :
{{log @outletArgs}}
Cela enregistrera les arguments dans la console de développement de votre navigateur. Ils apparaîtront sous forme d’objet Proxy — pour explorer la liste des arguments, développez le [[Target]] du proxy.
Dans notre exemple topic-above-posts, le sujet rendu est disponible sous @outletArgs.model. Nous pouvons donc ajouter le nom d’utilisateur du membre de l’équipe comme ceci :
<template>
<div class="alert alert-info">
Ce sujet a été créé par
{{@outletArgs.model.details.created_by.username}}
(un membre de l'
<a href="https://discourse.org/team">Équipe Discourse</a>)
</div>
</template>
Ajouter une logique plus complexe
Parfois, un template simple ne suffit pas. Pour ajouter une logique JavaScript à votre connecteur, mettez à niveau votre fichier .gjs pour exporter un composant basé sur une classe. Cela fonctionne exactement comme n’importe quelle autre définition de composant et peut inclure des injections de services.
Dans notre exemple topic-above-posts, nous pourrions vouloir rendre l’utilisateur différemment en fonction du paramètre du site « prioritize username in ux ». Le fichier .gjs pourrait ressembler à ceci :
.../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">
Ce sujet a été créé par
{{this.displayName}}
(un membre de l'
<a href="https://discourse.org/team">Équipe Discourse</a>)
</div>
</template>
}
Rendu conditionnel
Si vous ne souhaitez que votre contenu soit rendu que sous certaines conditions, il suffit souvent d’envelopper votre template dans un bloc {{#if}} de Handlebars. Si cela ne suffit pas, vous pouvez utiliser le hook shouldRender pour contrôler si votre template de connecteur est rendu ou non.
Tout d’abord, assurez-vous d’avoir un connecteur .gjs basé sur une classe comme décrit ci-dessus. Ensuite, ajoutez une fonction static shouldRender(). En étendant notre exemple :
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";
}
// ... (toute autre logique)
<template>{{! ... }}</template>
}
Maintenant, le connecteur ne sera rendu que lorsque le premier post du sujet a été créé par un membre de l’équipe.
shouldRender est évalué dans un contexte d’autotracking Glimmer. Les futures modifications de toute propriété référencée (par exemple outletArgs) entraîneront une réévaluation de la fonction.
Introduire de nouveaux outlets
Si vous avez besoin d’un outlet qui n’existe pas encore, n’hésitez pas à faire une pull request ou à ouvrir un sujet dans Development.
Ce document est sous contrôle de version — suggérez des modifications sur GitHub.