Utilizzare i connettori Plugin Outlet da un tema o plugin

Discourse include centinaia di Plugin Outlet che possono essere utilizzati per iniettare nuovo contenuto o sostituire contenuto esistente nell’interfaccia utente di Discourse. Gli ‘argomenti dell’outlet’ sono resi disponibili in modo che il contenuto possa essere personalizzato 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 tema posizioni degli outlet del plugin. (es. topic-above-posts).

Outlet wrapper

Alcuni outlet nel codice sorgente sembrano <PluginOutlet @name="foo" />. Questi ti permettono di iniettare nuovo contenuto. Altri outlet ‘avvolgeranno’ un’implementazione esistente del codice sorgente in questo modo

<PluginOutlet @name="foo">
  implementazione del codice sorgente
</PluginOutlet>

Definire un connettore per questo tipo di outlet ‘wrapper’ sostituirà l’implementazione del codice sorgente. Solo un tema/plugin attivo può contribuire con un connettore per un outlet wrapper del plugin.

Per gli outlet wrapper del plugin, puoi rendere l’implementazione originale del codice sorgente utilizzando la parola chiave {{yield}}. Questo può essere utile se vuoi sostituire l’implementazione del codice sorgente solo in determinate condizioni, o se desideri avvolgerla in qualcos’altro.

Definire il connettore

Una volta scelto un outlet, decidi un nome per il tuo connettore. Questo deve essere univoco tra tutti i temi/plugin installati in una determinata community. es. brand-official-topics

Nel tuo tema/plugin, definisci un nuovo connettore .gjs con un percorso formattato in questo modo:

:art: {theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs

:electric_plug: {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 il formato .gjs, consulta le guide di Ember.

Per il nostro ipotetico connettore “argomenti ufficiali del brand”, il file potrebbe sembrare

<template>
  <div class="alert alert-info">
    Questo argomento è stato creato da un membro del
    <a href="https://discourse.org/team">Team Discourse</a>
  </div>
</template>

Utilizzare gli argomenti dell’outlet

Gli Outlet del Plugin 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, l’argomento 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 argomento è stato creato da
    {{@outletArgs.model.details.created_by.username}}
    (un membro del
    <a href="https://discourse.org/team">Team Discourse</a>)
  </div>
</template>

Aggiungere logica più complessa

A volte, un semplice template 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 rendere l’utente in modo diverso in base all’impostazione del sito ‘prioritize username in ux’. Il file .gjs potrebbe sembrare qualcosa del genere:

.../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">Team Discourse</a>)
    </div>
  </template>
}

Rendering condizionale

Se vuoi che il tuo contenuto venga reso solo in determinate condizioni, spesso è sufficiente avvolgere il tuo template con un blocco {{#if}} handlebars. Se non è sufficiente, potresti voler utilizzare il hook shouldRender per controllare se il template del tuo connettore viene reso 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à reso solo quando il primo post dell’argomento è stato creato da un membro del team.

shouldRender viene valutato in un contesto di autotracking Glimmer. Le modifiche future a qualsiasi proprietà referenziata (es. outletArgs) causeranno la ri-valutazione della funzione.

Introdurre nuovi outlet

Se hai bisogno di un outlet che non esiste ancora, sentiti libero di fare una pull request, o apri un argomento in Development.


Questo documento è sotto controllo di versione - suggerisci modifiche su github.

39 Mi Piace
Using discourse's plugin outlets
What is the best way to integrate member applications?
Add HTML (Link) Next To Logo
Group Semantics
Can I put the search form at the top of our 404 page?
How to show user total post count beside name
Developing Discourse Plugins - Part 2 - Connect to a plugin outlet
Native theme support
Feedback on "on-discourse" javascript for setting up custom JS for each page?
Topic-timeline api.decorateWidget call has stopped working
Developing Discourse Plugins - Part 2 - Connect to a plugin outlet
Developing Discourse Themes & Theme Components
How to add btn before "sign in"
Minimizing Maintenance on Theme Customizations
How to add custom fields to models
Tags at the top of the topic list in a Category
I want to insert images (banner) between the topic answers. How do I start?
How to add a link shortcut to the area under the title
Baidu Search
Add Banner/HTML (Widget) before reply button
Upcoming Header Changes - Preparing Themes and Plugins
Upgrading Discourse to Ember 4
Converting modals from legacy controllers to new DModal component API
Need help integrating code wrote on Edittext to the Discourse
Settings not appearing
Add link to external SSO profile to profile page
How to add a custom button in user profile card?
(not recommended) Overriding Discourse templates from a Theme or Plugin
How to override the site-header.hbs file from custom theme?
Upcoming topic-list changes - how to prepare themes and plugins
Working with .erb templates in a plugin
How to Integrate a Custom Plugin in discourse UI
Templating of my "component" broke. How do I fix it?
Templating of my "component" broke. How do I fix it?
Modernizing inline script tags for templates & JS API
Custom Components -- add button or text at any plugin outlet
(not recommended) Overriding Discourse templates from a Theme or Plugin
Adding "latest topics" header in the main interface
Display Tags inline with thread title, instead of being on the bottom line
How to add a custom button in user profile card?
Discourse view file update does not reflect in browser
Discourse view file update does not reflect in browser
Add likes and views to search display
Using template hbs to add HTML content to a plugin outlet
Adding a billing section in the member section
Adding a billing section in the member section
How to modify the header HTML, but still remaining the default founctions
Removing support for "template overrides" and mobile-specific templates
How can i add image in login and register box
Most “traditional” or classic forum Category listing
Newbie help accessing code
How to add custom html next to logo using discourse plugin methods
Using the DModal API to render Modal windows (aka popups/dialogs) in Discourse
Air Theme
How to create a plugin with backend API calls to populate composer while drafting?
How to add a custom url text link on the login page
Add Text In Header Beside Logo
Split up theme Javascript into multiple files