Discourse inclut des centaines de Plugin Outlets qui peuvent être utilisés pour injecter de nouveaux contenus ou remplacer des contenus existants dans l’interface utilisateur de Discourse. Les « arguments de l’outlet » sont mis à disposition afin que le contenu puisse être personnalisé en fonction du contexte.
Choisir un outlet
Pour trouver le nom d’un plugin outlet, recherchez « <PluginOutlet » dans le code source de Discourse, ou utilisez le composant de thème Emplacements des plugin outlets. (par ex. topic-above-posts).
Outlets enveloppants (Wrapper outlets)
Certains outlets du code source ressemblent à <PluginOutlet @name="foo" />. Ils vous permettent d’injecter de nouveaux contenus. D’autres outlets « enveloppent » une implémentation existante du code source, comme ceci :
<PluginOutlet @name="foo">
implémentation du code source
</PluginOutlet>
Définir un connecteur pour ce type d’outlet « enveloppant » remplacera l’implémentation du code source. Un seul thème/plugin actif peut contribuer à un connecteur pour un plugin outlet enveloppant.
Pour les plugin outlets enveloppants, vous pouvez afficher l’implémentation originale du code source à l’aide du mot-clé {{yield}}. Cela peut être utile si vous ne souhaitez remplacer l’implémentation du code source que dans certaines conditions, ou si vous souhaitez l’encapsuler dans un autre élément.
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 au format suivant :
![]()
{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 en tant que 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
<a href="https://discourse.org/team">l'équipe Discourse</a>
</div>
</template>
Utiliser les arguments de l’outlet
Les Plugin Outlets fournissent des informations sur le contexte environnant via @outletArgs. Les arguments transmis à chaque outlet varient. Un moyen simple de visualiser les arguments consiste à ajouter ceci à votre modèle (template) :
{{log @outletArgs}}
Cela journalisera les arguments dans la console de développement de votre navigateur. Ils apparaîtront en tant qu’objet Proxy - pour explorer la liste des arguments, dépliez 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
<a href="https://discourse.org/team">l'équipe Discourse</a>)
</div>
</template>
Ajouter une logique plus complexe
Parfois, un simple modèle (template) 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 toute autre définition de composant et peut inclure des injections de services.
Dans notre exemple topic-above-posts, nous pourrions vouloir afficher l’utilisateur différemment en fonction du paramètre de 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
<a href="https://discourse.org/team">l'équipe Discourse</a>)
</div>
</template>
}
Rendu conditionnel
Si vous ne souhaitez que votre contenu soit rendu que dans certaines conditions, il suffit souvent d’entourer votre modèle avec un bloc {{#if}} handlebars. Si ce n’est pas suffisant, vous pouvez vouloir utiliser le hook shouldRender pour contrôler si le modèle de votre connecteur est rendu ou non.
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 prolongeant 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>
}
Désormais, le connecteur ne sera rendu que lorsque le premier message du sujet a été créé par un membre de l’équipe.
shouldRender est évalué dans un contexte de suivi automatique Glimmer. Les modifications futures de toutes les propriétés référencées (par ex. outletArgs) provoqueront la 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 à soumettre une pull request ou à ouvrir un sujet dans Development.
Ce document est sous contrôle de version - suggérez des modifications sur github.