Discourse include centinaia di Plugin Outlet che possono essere utilizzati per iniettare nuovo contenuto o sostituire contenuto esistente nell’interfaccia utente di Discourse. Gli ‘Outlet arguments’ sono resi disponibili per personalizzare il contenuto in base al contesto.
Scegliere un outlet
Per trovare il nome di un plugin outlet, cerca nel codice sorgente di Discourse “<PluginOutlet”, oppure utilizza il componente del tema plugin outlet locations. (ad esempio topic-above-posts).
Outlet di tipo wrapper
Alcuni outlet nel codice sorgente hanno la forma <PluginOutlet @name="foo" />. Questi ti permettono di iniettare nuovo contenuto. Altri outlet ‘avvolgono’ un’implementazione core esistente in questo modo:
<PluginOutlet @name="foo">
implementazione core
</PluginOutlet>
Definire un connettore per questo tipo di outlet ‘wrapper’ sostituirà l’implementazione core. Solo un tema/plugin attivo può contribuire con un connettore per un plugin outlet di tipo wrapper.
Per i plugin outlet di tipo wrapper, puoi renderizzare l’implementazione core originale utilizzando la parola chiave {{yield}}. Questo può essere utile se vuoi sostituire l’implementazione core solo in determinate condizioni, o se desideri avvolgerla in qualcosa.
Definire il connettore
Una volta scelto un outlet, decidi un nome per il tuo connettore. Questo deve essere unico tra tutti i temi/plugin installati in una data community. Ad esempio: brand-official-topics
Nel tuo tema/plugin, definisci un nuovo connettore .gjs con un percorso formattato in questo modo:
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
Il contenuto di questi file verrà renderizzato come un componente Ember. Per informazioni generali su Ember e sul formato .gjs, consulta le guide di Ember.
Per il nostro ipotetico connettore “brand official topics”, il file potrebbe apparire così:
<template>
<div class="alert alert-info">
Questo argomento è stato creato da un membro del
<a href="https://discourse.org/team">Discourse Team</a>
</div>
</template>
Utilizzare gli outlet arguments
I Plugin Outlets forniscono informazioni sul contesto circostante tramite @outletArgs. Gli argomenti passati a ogni outlet variano. Un modo semplice per visualizzare gli argomenti è aggiungere questo al tuo template:
{{log @outletArgs}}
Questo registrerà gli argomenti nella console degli sviluppatori del tuo browser. Appariranno come un oggetto Proxy: per esplorare l’elenco degli argomenti, espandi [[Target]] del proxy.
Nel nostro esempio topic-above-posts, l’argomento renderizzato è disponibile sotto @outletArgs.model. Quindi possiamo aggiungere il nome utente del membro del team in questo modo:
<template>
<div class="alert alert-info">
Questo argomento è stato creato da
{{@outletArgs.model.details.created_by.username}}
(un membro del
<a href="https://discourse.org/team">Discourse Team</a>)
</div>
</template>
Aggiungere logica più complessa
A volte, un template semplice non è sufficiente. Per aggiungere logica Javascript al tuo connettore, aggiorna il tuo file .gjs per esportare un componente basato su classe. Questo funziona esattamente come qualsiasi altra definizione di componente e può includere iniezioni di servizi.
Nel nostro esempio topic-above-posts, potremmo voler renderizzare l’utente in modo diverso in base all’impostazione del sito ‘prioritize username in ux’. Il file .gjs potrebbe assomigliare a questo:
.../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">
Questo argomento è stato creato da
{{this.displayName}}
(un membro del
<a href="https://discourse.org/team">Discourse Team</a>)
</div>
</template>
}
Rendering condizionale
Se vuoi che il tuo contenuto venga renderizzato solo in determinate condizioni, spesso è sufficiente avvolgere il tuo template con un blocco {{#if}} di Handlebars. Se ciò non basta, potresti voler utilizzare il hook shouldRender per controllare se il template del tuo connettore deve essere renderizzato affatto.
Innanzitutto, assicurati di avere un connettore .gjs basato su classe come descritto sopra. Quindi, aggiungi una funzione static shouldRender(). Estendendo il nostro esempio:
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";
}
// ... (qualsiasi altra logica)
<template>{{! ... }}</template>
}
Ora il connettore verrà renderizzato solo quando il primo post dell’argomento è stato creato da un membro del team.
shouldRender viene valutato in un contesto di autotracking di Glimmer. Le future modifiche a qualsiasi proprietà referenziata (ad esempio outletArgs) faranno sì che la funzione venga rieseguita.
Introdurre nuovi outlet
Se hai bisogno di un outlet che non esiste ancora, sentiti libero di fare una pull request o aprire un argomento in Development.
Questo documento è controllato tramite versioning: suggerisci modifiche su github.