Discourse comprend des centaines de Plugin Outlets (points d’extension) qui peuvent être utilisés pour injecter du nouveau contenu ou remplacer du contenu existant dans l’interface Discourse. Des « arguments de sortie » sont mis à disposition afin que le contenu puisse être personnalisé en fonction du contexte.
Choisir un point d’extension
Pour trouver le nom d’un point d’extension, recherchez « <PluginOutlet » dans le code source de Discourse, ou utilisez le composant thème Emplacements des points d’extension. (par exemple topic-above-posts).
Points d’extension enveloppeurs
Certains points d’extension du code source ressemblent à <PluginOutlet @name="foo" />. Ceux-ci vous permettent d’injecter du nouveau contenu. D’autres points d’extension « enveloppent » une implémentation existante du code source comme suit :
<PluginOutlet @name="foo">
implémentation du code source
</PluginOutlet>
Définir un connecteur pour ce type de point d’extension « enveloppeur » remplacera l’implémentation du code source. Un seul thème/plugin actif peut fournir un connecteur pour un point d’extension enveloppeur.
Pour les points d’extension enveloppeurs, vous pouvez rendre l’implémentation originale du code source en utilisant le mot-clé {{yield}}. Cela peut être utile si vous souhaitez uniquement remplacer l’implémentation du code source dans certaines conditions, ou si vous souhaitez l’envelopper dans autre chose.
Définir le connecteur
Une fois que vous avez choisi un point d’extension, choisissez un nom pour votre connecteur. Ce nom 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/{nom-du-point-d-extension}/{nom-du-connecteur}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{nom-du-point-d-extension}/{nom-du-connecteur}.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 « sujets officiels de la marque », le fichier pourrait ressembler à ceci :
<template>
<div class="alert alert-info">
Ce sujet a été créé par un membre de l’équipe
<a href="https://discourse.org/team">Discourse</a>
</div>
</template>
Utiliser les arguments de sortie
Les Plugin Outlets fournissent des informations sur le contexte environnant via @outletArgs. Les arguments transmis à chaque point d’extension varient. Un moyen simple de visualiser les arguments est d’ajouter ceci à votre modèle :
{{log @outletArgs}}
Cela enregistrera 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é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 suit :
<template>
<div class="alert alert-info">
Ce sujet a été créé par
{{@outletArgs.model.details.created_by.username}}
(un membre de l’équipe
<a href="https://discourse.org/team">Discourse</a>)
</div>
</template>
Ajouter une logique plus complexe
Parfois, un simple modèle 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 « privilégier le nom d’utilisateur dans l’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’équipe
<a href="https://discourse.org/team">Discourse</a>)
</div>
</template>
}
Rendu conditionnel
Si vous souhaitez que votre contenu ne soit rendu que dans certaines conditions, il suffit souvent d’envelopper votre modèle avec un bloc {{#if}} Handlebars. Si cela ne suffit pas, vous pouvez utiliser le hook shouldRender pour contrôler si le modèle de votre connecteur est rendu du tout.
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 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>
}
Maintenant, 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 changements futurs de toutes les propriétés référencées (par exemple outletArgs) entraîneront la réévaluation de la fonction.
Introduire de nouveaux points d’extension
Si vous avez besoin d’un point d’extension qui n’existe pas encore, n’hésitez pas à faire une demande de tirage (pull request) ou à ouvrir un sujet dans Development.
Ce document est sous contrôle de version - suggérez des modifications sur github.