Idealmente, ao personalizar o Discourse por meio de temas/plugins, você deve usar CSS, a API de Plugin JavaScript ou saídas de plugin (plugin outlets). Se nenhuma dessas opções funcionar para o seu caso de uso, sinta-se à vontade para abrir um PR no núcleo do Discourse ou iniciar um tópico Dev aqui no Meta. Estamos sempre felizes em discutir a adição de novas saídas/APIs para facilitar a personalização.
Se você esgotou todas as outras opções, pode ser necessário recorrer a substituições de modelo (template overrides). Esta técnica permite substituir o modelo inteiro de qualquer Componente Ember ou Rota do seu tema/plugin.
Esta não é uma maneira recomendada de personalizar o Discourse. Mudanças do dia a dia no núcleo do Discourse irão entrar em conflito com sua substituição de modelo eventualmente, potencialmente causando erros catastróficos ao renderizar o fórum.
Se você decidir seguir este caminho, certifique-se de ter testes automatizados e processos de QA suficientes para detectar regressões. Se você distribuir um tema/plugin com substituições de modelo, certifique-se de que os administradores do fórum estejam cientes dos riscos de estabilidade que seu tema/plugin acarreta.
![]()
![]()
Atualização de Outubro de 2023: Para novos recursos, o Discourse está migrando cada vez mais para o uso de componentes criados usando o formato de arquivo
.gjsdo Ember. Os modelos para esses componentes são definidos inline e não podem ser substituídos por temas/plugins.Doravante, todas as personalizações de modelo devem ser feitas usando Plugin Outlets
Eu entendo que isso quebrará em um futuro próximo, mostre-me a documentação de qualquer maneira
Substituindo Modelos de Componentes
Para substituir um modelo de Componente Ember (ou seja, qualquer coisa sob components/* no núcleo do Discourse), você deve criar um arquivo .hbs com o mesmo nome no seu tema/plugin. Por exemplo, para substituir o modelo do componente badge-button no núcleo do Discourse, você criaria um arquivo de modelo no seu tema/plugin neste local:
{theme}/javascripts/discourse/templates/components/badge-button.hbs
{plugin}/assets/javascripts/discourse/templates/components/badge-button.hbs
A substituição deve estar sempre aninhada dentro do diretório /templates, mesmo que o componente principal tenha um modelo ‘co-localizado’.
Substituindo Modelos de Rota
Substituir modelos de rota (ou seja, todos os modelos que não são de componentes sob templates/*) funciona da mesma forma que os componentes. Crie um modelo com o mesmo nome no seu tema/plugin. Por exemplo, para substituir discovery.hbs no núcleo, você criaria um arquivo como
{theme}/javascripts/discourse/templates/discovery.hbs
{plugin}/assets/javascripts/discourse/templates/discovery.hbs
Substituindo Modelos ‘Brutos’ (.hbr)
O sistema de modelo “bruto” do Discourse será em breve substituído por componentes Ember regulares. Mas, por enquanto, substituir modelos brutos funciona da mesma forma que modelos Ember. Por exemplo, para substituir topic-list-item.hbr no núcleo, você poderia criar um arquivo como:
{theme}/javascripts/discourse/templates/list/topic-list-item.hbr
{plugin}/assets/javascripts/discourse/templates/list/topic-list-item.hbr
Interação entre Múltiplos Temas / Plugins
Se múltiplos temas/plugins instalados substituírem o mesmo modelo, o ‘vencedor’ é aquele com a classificação numérica mais baixa nesta lista:
- Substituições de tema (o maior ‘id’ de tema vence)
- Substituições de plugin (o nome de plugin alfabeticamente mais recente vence)
- Núcleo
Esta precedência também significa que você pode substituir modelos de plugin a partir de temas. Tecnicamente, você também pode substituir modelos de tema a partir de outros temas, e modelos de plugin a partir de outros plugins, mas o comportamento pode ser surpreendente devido à dependência do nome do plugin e do id do tema.
Como isso funciona?
O Discourse monta e prioriza os modelos na classe DiscourseTemplateMap. Para modelos de componentes co-localizados, essa informação é usada durante a inicialização do aplicativo para substituir as associações de modelo do núcleo. Para todos os outros modelos, o mapa é usado por o resolvedor em tempo de execução para buscar o modelo correto.
Este documento tem controle de versão - sugira alterações no github.