Como adicionar HTML personalizado após "post_1"

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.