Discourse incluye cientos de puntos de extensión (Plugin Outlets) que pueden usarse para inyectar nuevo contenido o reemplazar contenido existente en la interfaz de Discourse. Se ponen a disposición los “argumentos de salida” para que el contenido pueda personalizarse según el contexto.
Elegir un punto de extensión
Para encontrar el nombre de un punto de extensión, busca en el núcleo de Discourse “<PluginOutlet” o utiliza el componente de tema ubicaciones de puntos de extensión. (por ejemplo, topic-above-posts).
Puntos de extensión envoltorios
Algunos puntos de extensión en el núcleo se ven como <PluginOutlet @name="foo" />. Estos te permiten inyectar nuevo contenido. Otros puntos de extensión “envolverán” una implementación existente del núcleo de esta manera:
<PluginOutlet @name="foo">
implementación del núcleo
</PluginOutlet>
Definir un conector para este tipo de punto de extensión “envoltorio” reemplazará la implementación del núcleo. Solo un tema o complemento activo puede aportar un conector para un punto de extensión envoltorio.
Para los puntos de extensión envoltorios, puedes renderizar la implementación original del núcleo usando la palabra clave {{yield}}. Esto puede ser útil si solo deseas reemplazar la implementación del núcleo bajo ciertas condiciones, o si deseas envolverla en algo.
Definir el conector
Una vez que hayas elegido un punto de extensión, decide un nombre para tu conector. Este debe ser único entre todos los temas/complementos instalados en una comunidad dada. por ejemplo, brand-official-topics
En tu tema/complemento, define un nuevo conector .gjs con una ruta formateada así:
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
El contenido de estos archivos se renderizará como un Componente de Ember. Para información general sobre Ember y el formato .gjs, consulta las guías de Ember.
Para nuestro hipotético conector “temas oficiales de la marca”, el archivo podría verse así:
<template>
<div class="alert alert-info">
Este tema fue creado por un miembro del
<a href="https://discourse.org/team">Equipo de Discourse</a>
</div>
</template>
Usar argumentos de salida
Los puntos de extensión proporcionan información sobre el contexto circundante a través de @outletArgs. Los argumentos pasados a cada salida varían. Una forma fácil de ver los argumentos es agregar esto a tu plantilla:
{{log @outletArgs}}
Esto registrará los argumentos en la consola de desarrollador de tu navegador. Aparecerán como un objeto Proxy: para explorar la lista de argumentos, expande el [[Target]] del proxy.
En nuestro ejemplo topic-above-posts, el tema renderizado está disponible bajo @outletArgs.model. Así que podemos agregar el nombre de usuario del miembro del equipo así:
<template>
<div class="alert alert-info">
Este tema fue creado por
{{@outletArgs.model.details.created_by.username}}
(un miembro del
<a href="https://discourse.org/team">Equipo de Discourse</a>)
</div>
</template>
Agregar lógica más compleja
A veces, una plantilla simple no es suficiente. Para agregar lógica de Javascript a tu conector, actualiza tu archivo .gjs para exportar un componente basado en clase. Esto funciona igual que cualquier otra definición de componente y puede incluir inyecciones de servicios.
En nuestro ejemplo topic-above-posts, podríamos querer renderizar al usuario de manera diferente según la configuración del sitio “priorizar nombre de usuario en UX”. El archivo .gjs podría verse algo así:
.../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">
Este tema fue creado por
{{this.displayName}}
(un miembro del
<a href="https://discourse.org/team">Equipo de Discourse</a>)
</div>
</template>
}
Renderizado condicional
Si solo deseas que tu contenido se renderice bajo ciertas condiciones, a menudo basta con envolver tu plantilla con un bloque {{#if}} de handlebars. Si eso no es suficiente, puedes usar el gancho shouldRender para controlar si tu plantilla de conector se renderiza en absoluto.
Primero, asegúrate de tener un conector .gjs basado en clase como se describió anteriormente. Luego, agrega una función static shouldRender(). Extendiendo nuestro ejemplo:
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";
}
// ... (cualquier otra lógica)
<template>
{{! ... }}
</template>
}
Ahora el conector solo se renderizará cuando la primera publicación del tema haya sido creada por un miembro del equipo.
shouldRender se evalúa en un contexto de autoseguimiento de Glimmer. Los cambios futuros en cualquier propiedad referenciada (por ejemplo, outletArgs) causarán que la función se reevalúe.
Introducir nuevos puntos de extensión
Si necesitas un punto de extensión que aún no existe, siéntete libre de hacer una solicitud de extracción (pull request) o abrir un tema en Development.
Este documento está controlado por versiones - sugiere cambios en github.