As postagens são widgets, o que significa que o que você está tentando fazer envolverá um pouco mais de trabalho do que apenas adicionar HTML.
Os temas do Discourse têm a capacidade de decorar widgets, então você pode aproveitar isso.
A decoração de um widget é explicada no link acima, então vamos focar no que você está tentando fazer: adicionar marcação após a primeira postagem em cada tópico.
Comece adicionando a marcação a todas as postagens. Algo assim:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
return helper.h("div", "texto de teste");
});
</script>
na seção de cabeçalho do seu tema. Isso deve ser suficiente para adicionar “texto de teste” abaixo de cada postagem.
Vamos analisar o script acima:
api.decorateWidget("post:after", helper => {
chama o método decorateWidget, onde o widget alvo é post e a localização alvo é after. Ou seja, após um widget de postagem.
helper é um helper integrado que dá acesso a várias funcionalidades que explicarei mais adiante.
return helper.h("div", "texto de teste")
Esta é a marcação adicional desejada que você quer adicionar. Você pode notar que não há HTML ali, e isso ocorre porque os widgets do Discourse emitem nós virtuais e não HTML bruto.
Explicar o que são nós virtuais ou como a sintaxe funciona está fora do escopo deste tópico, então vou pular isso. Adicionei uma nota para escrever um tutorial sobre a criação de nós virtuais, mas aqui estão alguns exemplos por enquanto:
helper.h("div", "texto de teste")
renderiza
<div>texto de teste</div>
e
return helper.h("div#custom-ad", [
helper.h(
"a.custom-ad-link",
{ href: "example.com" },
helper.h("img", { src: "https://picsum.photos/id/74/750/90" })
)
]);
renderizará
<div id="custom-ad">
<a href="example.com" class="custom-ad-link">
<img src="https://picsum.photos/id/74/750/90">
</a>
</div>
Em resumo, um nó se parece com isso:
helper.h(selector, {properties}, children)
Explicarei isso com mais detalhes no tutorial sobre nós virtuais.
Então, agora que você tem os nós prontos, basta adicionar todo o script à seção de cabeçalho do seu tema, algo assim:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
return helper.h("div#custom-ad", [
helper.h(
"a.custom-ad-link",
{ href: "example.com" },
helper.h("img", { src: "https://picsum.photos/id/74/750/90" })
)
]);
});
</script>
No entanto, ainda há um problema aqui: o anúncio será inserido abaixo de cada postagem no fluxo, o que não é ideal.
É aqui que o helper se torna útil. Os atributos da postagem são passados para o helper, então você pode fazer um rápido:
console.log(helper)
Você poderá ver todos os atributos da postagem disponíveis para trabalhar.
esses são apenas exemplos, há mais coisas lá.
Felizmente, o atributo firstPost está disponível para nós aqui, então tudo o que resta é usá-lo em uma condição que renderizará a marcação do anúncio apenas se for realmente a primeira postagem; caso contrário, nada acontece. Algo assim:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
const firstPost = helper.attrs.firstPost;
const h = helper.h;
if (firstPost) {
return h("div#custom-ad", [
h(
"a.custom-ad-link",
{ href: "example.com" },
h("img", { src: "https://picsum.photos/id/74/750/90" })
)
]);
}
});
</script>
Isso inserirá seu anúncio apenas após a primeira postagem. Uma coisa adicional a fazer aqui é adicionar uma altura à imagem; caso contrário, ela causará tremores ao carregar. Como mencionei brevemente acima, o atributo height para a tag de imagem é uma propriedade, então você precisa adicioná-lo ao lado do src.
Com tudo isso reunido, aqui está o código final para o que você está tentando alcançar:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
const firstPost = helper.attrs.firstPost;
const h = helper.h;
if (firstPost) {
return h("div#custom-ad", [
h(
"a.custom-ad-link",
{ href: "example.com" },
h("img", { src: "https://picsum.photos/id/74/750/90", height: "90" })
)
]);
}
});
</script>
Uma última observação que quero destacar é que você pode realmente usar HTML bruto se os nós virtuais provarem ser muito complicados, mas não é recomendado e é muito melhor usar nós virtuais. Então, o mesmo script com HTML bruto ficaria assim:
<script type="text/discourse-plugin" version="0.8">
const RawHtml = require("discourse/widgets/raw-html").default;
api.decorateWidget("post:after", helper => {
const firstPost = helper.attrs.firstPost;
if (firstPost) {
return [
new RawHtml({
html: `<div id="custom-ad">
<a href="example.com">
<img src="https://picsum.photos/id/74/750/90" height="90">
</a>
</div>`
})
];
}
});
</script>
mas, novamente, isso não é recomendado.


