O Discourse inclui centenas de Plugin Outlets que podem ser usados para injetar novo conteúdo ou substituir conteúdo existente na interface do Discourse. Os ‘argumentos de outlet’ ficam disponíveis para que o conteúdo possa ser personalizado com base no contexto.
Escolhendo um outlet
Para encontrar o nome de um plugin outlet, pesquise no núcleo do Discourse por “<PluginOutlet”, ou use o componente de tema localizações de plugin outlet. (ex.: topic-above-posts).
Outlets de envoltório (wrapper)
Alguns outlets no núcleo se parecem com <PluginOutlet @name="foo" />. Eles permitem que você injete novo conteúdo. Outros outlets ‘envolvem’ uma implementação existente do núcleo, como esta:
<PluginOutlet @name="foo">
implementação do núcleo
</PluginOutlet>
Definir um conector para esse tipo de outlet de ‘envoltório’ substituirá a implementação do núcleo. Apenas um tema/plugin ativo pode contribuir com um conector para um plugin outlet de envoltório.
Para plugin outlets de envoltório, você pode renderizar a implementação original do núcleo usando a palavra-chave {{yield}}. Isso pode ser útil se você quiser substituir a implementação do núcleo apenas sob certas condições, ou se quiser envolvê-la em algo.
Definindo o conector
Depois de escolher um outlet, decida um nome para o seu conector. Ele precisa ser único entre todos os temas / plugins instalados em uma determinada comunidade. ex.: brand-official-topics
No seu tema / plugin, defina um novo conector .gjs com um caminho formatado da seguinte forma:
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
O conteúdo desses arquivos será renderizado como um Componente Ember. Para informações gerais sobre o Ember e o formato .gjs, confira os guias do Ember.
Para o nosso conector hipotético “brand official topics”, o arquivo poderia se parecer com:
<template>
<div class="alert alert-info">
Este tópico foi criado por um membro da
<a href="https://discourse.org/team">Equipe Discourse</a>
</div>
</template>
Usando argumentos de outlet
Os Plugin Outlets fornecem informações sobre o contexto circundante via @outletArgs. Os argumentos passados para cada outlet variam. Uma maneira fácil de visualizar os argumentos é adicionar isto ao seu modelo:
{{log @outletArgs}}
Isso registrará os argumentos no console de desenvolvedor do seu navegador. Eles aparecerão como um objeto Proxy - para explorar a lista de argumentos, expanda o [[Target]] do proxy.
No nosso exemplo topic-above-posts, o tópico renderizado está disponível em @outletArgs.model. Portanto, podemos adicionar o nome de usuário do membro da equipe da seguinte forma:
<template>
<div class="alert alert-info">
Este tópico foi criado por
{{@outletArgs.model.details.created_by.username}}
(um membro da
<a href="https://discourse.org/team">Equipe Discourse</a>)
</div>
</template>
Adicionando lógica mais complexa
Às vezes, um modelo simples não é suficiente. Para adicionar lógica JavaScript ao seu conector, atualize seu arquivo .gjs para exportar um componente baseado em classe. Isso funciona exatamente como qualquer outra definição de componente e pode incluir injeções de serviço.
No nosso exemplo topic-above-posts, podemos querer renderizar o usuário de forma diferente com base na configuração do site ‘prioritize username in ux’. O arquivo .gjs poderia se parecer com:
.../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 tópico foi criado por
{{this.displayName}}
(um membro da
<a href="https://discourse.org/team">Equipe Discourse</a>)
</div>
</template>
}
Renderização condicional
Se você quiser que seu conteúdo seja renderizado apenas sob certas condições, muitas vezes é suficiente envolver seu modelo com um bloco {{#if}} do handlebars. Se isso não for suficiente, você pode querer usar o hook shouldRender para controlar se o modelo do seu conector será renderizado ou não.
Primeiro, certifique-se de ter um conector .gjs baseado em classe, conforme descrito acima. Em seguida, adicione uma função static shouldRender(). Estendendo nosso exemplo:
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";
}
// ... (qualquer outra lógica)
<template>
{{! ... }}
</template>
}
Agora o conector será renderizado apenas quando a primeira postagem do tópico foi criada por um membro da equipe.
shouldRender é avaliado em um contexto de autotracking do Glimmer. Mudanças futuras em qualquer propriedade referenciada (ex.: outletArgs) causarão a reavaliação da função.
Introduzindo novos outlets
Se você precisar de um outlet que ainda não existe, sinta-se à vontade para fazer um pull request ou abrir um tópico em Development.
Este documento é controlado por versão - sugira alterações no github.