Le problème : je souhaite que les utilisateurs puissent publier en tant que personnages de jeu de rôle. J’aimerais qu’ils puissent insérer un modèle dans un message — quelque chose comme ce qui suit :
[wrap="characterpost"]
[characterav]https://image.link.example.png[/characterav]
[charactername][[Nom du personnage]][/charactername]
[/wrap]
Et ensuite utiliser un script pour que l’image remplace l’avatar d’origine et que le lien vers le sujet du nom du personnage soit placé devant le nom d’utilisateur. Par exemple, si le message affiche normalement « Nom d’utilisateur », je souhaite le remplacer par « Nom du personnage joué par Nom d’utilisateur ».
(Le « Nom du personnage » inclurait un lien vers un sujet contenant la fiche du personnage, en espérant utiliser simplement le composant de thème des liens wiki pour la facilité d’utilisation.)
J’ai collé un squelette de message dans un Codepen et j’ai réussi à écrire un peu de JavaScript qui ferait exactement cela. Cependant, quand il a fallu l’ajouter dans un décorateur de message et le faire fonctionner en direct avec l’API, je suis arrivé à une impasse.
Voici ce que j’ai actuellement dans common>header :
<script type="text/discourse-plugin" version="0.8">
api.decorateCookedElement(
element => {
// trouver la balise characterpost dans le message
const characterPost = element.querySelector('[data-wrap="characterpost"]');
// trouver le parent de la balise characterpost, qui contient l'avatar et le nom d'utilisateur
const characterPostParent = characterPost.closest('article');
// le rendre rouge pour voir si ça fonctionne
characterPostParent.style.backgroundColor = "red";
},
{
id: 'render-character-post', onlyStream: true, afterAdopt: true
}
);
</script>
Cela provoque une erreur. Est-il possible d’accéder à l’élément enveloppe « article » des messages en utilisant decorateCookedElement afin que je puisse accéder au nom d’utilisateur et à l’avatar ? Si ce n’est pas le cas, comment puis-je m’y prendre ?
Je suis tombé sur ce post et j’ai pensé que je pourrais essayer !
Voici la première version ; j’espère que le code n’est pas trop horrible.
Je n’ai pas testé de manière exhaustive tous les cas limites. C’est un point de départ.
Format d’enroulement attendu : [wrap=character avatar=\"<URL>\"]<Nom>[/wrap]
Assurez-vous qu’il y a une ligne vide sous [wrap]
Vous pouvez personnaliser le nom du personnage avec CSS (voir les classes character et character-extra)
Faites-moi savoir si vous rencontrez des problèmes
Head
<script type="text/discourse-plugin" version="0.8.13">
let characters = new Map();
function searchTag(obj, tag) {
if (!obj || !obj.firstObject) return;
const firstObj = obj.firstObject;
return firstObj.tagName === tag ? firstObj : searchTag(firstObj.children, tag);
}
api.addPostTransformCallback(post =>
{
if (post.post_number <= 1 || post.post_type !== 1) {
return;
}
const matches = post.cooked.match(/data-wrap="character"\s+data-avatar="(?<avatar>[^"]+)"\s+data-name="(?<name>[^"]+)"/i);
if (!matches) {
characters.delete(post.id);
return;
}
// TODO: sanity check for avatar/name
const {name, avatar} = matches.groups;
characters.set(post.id, {name, avatar});
});
api.reopenWidget("post-avatar", {
html(attrs) {
const html = this._super(attrs);
if (attrs.id && characters.has(attrs.id)) {
const imageHtml = searchTag(html, 'IMG');
if (imageHtml) {
imageHtml.properties.attributes.src = characters.get(attrs.id).avatar;
}
}
return html;
}
});
api.reopenWidget("poster-name", {
html(attrs) {
let html = this._super(attrs);
if (attrs.id && characters.has(attrs.id)) {
const h = require("virtual-dom").h;
html = [
h('span.character', this.userLink(attrs, characters.get(attrs.id).name)),
h('span.character-extra', 'played by'), // optional
...html
];
}
return html;
}
});
</script>
C’est très cool, merci de partager ! Je cherchais aussi quelque chose de similaire. Savez-vous si cela affecte également la façon dont les publications apparaissent dans les résultats de recherche ?
Bonne question ! Le nom de la balise et son contenu font partie du contenu du message ; cela pourrait affecter le résultat de la recherche.
Je vais essayer quelque chose de plus propre, comme utiliser une modale et enregistrer dans des champs personnalisés à la place.
EDIT : Je pense que j’ai mal compris :smile : si vous parlez des changements apparaissant dans le résultat de la recherche, la réponse est non (ni le HTML n’apparaîtra).
Il pourrait être judicieux de proposer, peut-être dans le wiki communautaire, un guide de modèles de forum. Souvent, les gens viennent chercher des idées sur différents types de configurations de forum. Dans ce cas, cela pourrait être un peu spécifique. Mais un modèle de jeu de rôle sur table qui inclut cette fonctionnalité que vous avez créée.