Les publications sont des widgets, ce qui signifie que ce que vous essayez de faire impliquera un peu plus de travail que simplement ajouter du HTML.
Les thèmes Discourse ont la capacité de décorer des widgets, vous pouvez donc en tirer parti.
La décoration d’un widget est expliquée dans le lien ci-dessus, concentrons-nous donc sur ce que vous essayez de faire : ajouter du balisage après le premier message de chaque sujet.
Commencez par ajouter le balisage à tous les messages. Quelque chose comme ceci :
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
return helper.h("div", "texte de test");
});
</script>
dans la section en-tête de votre thème. Cela devrait suffire pour ajouter du « texte de test » sous chaque message.
Décomposons le script ci-dessus.
api.decorateWidget("post:after", helper => {
appelle la méthode decorateWidget, le widget cible étant post et l’emplacement cible étant after. Donc, après un widget de message.
helper est un helper intégré qui vous donne accès à un ensemble de fonctionnalités que j’expliquerai plus tard.
return helper.h("div", "texte de test")
C’est le balisage supplémentaire souhaité que vous souhaitez ajouter. Vous remarquerez peut-être qu’il n’y a pas de HTML dedans, et c’est parce que les widgets Discourse émettent des nœuds virtuels et non du HTML brut.
Expliquer ce que sont les nœuds virtuels ou comment fonctionne la syntaxe est hors du cadre de ce sujet, donc je vais passer à autre chose. J’ai ajouté une note pour écrire un tutoriel sur la création de nœuds virtuels, mais voici quelques exemples pour l’instant.
helper.h("div", "texte de test")
rend :
<div>texte de test</div>
et
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" })
)
]);
rendra :
<div id="custom-ad">
<a href="example.com" class="custom-ad-link">
<img src="https://picsum.photos/id/74/750/90">
</a>
</div>
En résumé, un nœud ressemble à ceci :
helper.h(sélecteur, {propriétés}, enfants)
J’expliquerai cela plus en détail dans le tutoriel sur les nœuds virtuels.
Donc, maintenant que vous avez les nœuds prêts, vous n’aurez qu’à ajouter tout le script à la section en-tête de votre thème, quelque chose comme ceci :
<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>
Cependant, il y a encore un problème ici : la publicité sera insérée sous chaque message du flux, ce qui n’est pas idéal.
C’est là que le helper s’avère utile : les attributs du message sont transmis au helper, vous pouvez donc faire rapidement :
console.log(helper)
Vous pourrez voir tous les attributs du message disponibles pour travailler.
ce ne sont que des exemples, il y en a plus.
Heureusement, l’attribut firstPost est disponible pour nous ici, il ne vous reste plus qu’à l’intégrer dans une condition qui n’affichera le balisage de la publicité que s’il s’agit bien du premier message, sinon rien ne se passera. Quelque chose comme ceci :
<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>
cela insérera votre publicité uniquement après le premier message. Une chose supplémentaire à faire ici est d’ajouter une hauteur à l’image, sinon cela provoquera des saccades pendant le chargement. Comme je l’ai brièvement mentionné ci-dessus, l’attribut height pour la balise image est une propriété, vous devez donc l’ajouter à côté de src.
Avec tout cela assemblé, voici le code final pour ce que vous essayez d’accomplir :
<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>
Une dernière remarque que je tiens à souligner est que vous pouvez en fait utiliser du HTML brut si les nœuds virtuels s’avèrent trop complexes, mais ce n’est pas recommandé et il est beaucoup mieux d’utiliser des nœuds virtuels. Donc, le même script avec du HTML brut ressemblerait à ceci :
<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>
mais encore une fois, cela n’est pas recommandé.