Discourse include centinaia di Plugin Outlet che possono essere utilizzati per iniettare nuovo contenuto o sostituire il contenuto esistente nell’interfaccia di Discourse. Gli ‘argomenti dell’outlet’ sono resi disponibili in modo che il contenuto possa essere personalizzato in base al contesto.
Scelta di un outlet
Per trovare il nome di un plugin outlet, cerca “<PluginOutlet” nel codice sorgente di Discourse, oppure utilizza il componente tema posizioni degli outlet dei plugin. (es. topic-above-posts).
Outlet wrapper
Alcuni outlet nel core hanno l’aspetto di <PluginOutlet @name="foo" />. Questi ti permettono di iniettare nuovo contenuto. Altri outlet ‘avvolgono’ un’implementazione core esistente come questa:
<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 wrapper.
Per gli outlet dei plugin wrapper, è possibile rendere l’implementazione core originale utilizzando la parola chiave {{yield}}. Questo può essere utile se si desidera sostituire l’implementazione core solo in determinate condizioni, oppure se si desidera avvolgerla in qualcos’altro.
Definizione del connettore
Una volta scelto un outlet, decidi un nome per il tuo connettore. Questo deve essere univoco tra tutti i temi / plugin installati su una determinata community. es. 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à reso 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 topic è stato creato da un membro del
<a href="https://discourse.org/team">Discourse Team</a>
</div>
</template>
Utilizzo degli argomenti dell’outlet
I Plugin Outlet forniscono informazioni sul contesto circostante tramite @outletArgs. Gli argomenti passati a ciascun outlet variano. Un modo semplice per visualizzare gli argomenti è aggiungere questo al tuo template:
{{log @outletArgs}}
Questo registrerà gli argomenti nella console di sviluppo del browser. Appariranno come un oggetto Proxy - per esplorare l’elenco degli argomenti, espandi il [[Target]] del proxy.
Nel nostro esempio topic-above-posts, il topic reso è disponibile sotto @outletArgs.model. Quindi possiamo aggiungere il nome utente del membro del team in questo modo:
<template>
<div class="alert alert-info">
Questo topic è stato creato da
{{@outletArgs.model.details.created_by.username}}
(un membro del
<a href="https://discourse.org/team">Discourse Team</a>)
</div>
</template>
Aggiunta di logiche più complesse
A volte, un semplice template non è sufficiente. Per aggiungere logiche 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 rendere l’utente in modo diverso in base all’impostazione del sito ‘prioritize username in ux’. Il file .gjs potrebbe apparire così:
.../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 topic è stato creato da
{{this.displayName}}
(un membro del
<a href="https://discourse.org/team">Discourse Team</a>)
</div>
</template>
}
Rendering condizionale
Se si desidera che il proprio contenuto venga reso solo in determinate condizioni, è spesso sufficiente avvolgere il template con un blocco {{#if}} di handlebars. Se ciò non è sufficiente, si potrebbe voler utilizzare l’hook shouldRender per controllare se il template del connettore venga reso o meno.
Prima di tutto, 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à reso solo quando il primo post del topic è stato creato da un membro del team.
shouldRender viene valutato in un contesto di autotracking Glimmer. Le modifiche future a qualsiasi proprietà di riferimento (es. outletArgs) causeranno la rivalutazione della funzione.
Introduzione di nuovi outlet
Se hai bisogno di un outlet che non esiste ancora, non esitare a creare una pull request o aprire un topic in Development.
Questo documento è sotto controllo di versione - suggerisci modifiche su github.