El problema: quiero que los usuarios puedan publicar como personajes de RPG. Me gustaría que pudieran insertar una plantilla en una publicación, algo como lo siguiente:
Y luego usar un script para que la imagen reemplace el avatar original y el enlace del tema del nombre del personaje aparezca antes del nombre de usuario. Por ejemplo, si la publicación normalmente dice «Username», quiero reemplazarlo por «Character Name played by Username».
(«Character Name» incluiría un enlace a un tema con la ficha del personaje, usando idealmente solo el componente de tema de wikilinks por facilidad de uso.)
Pegué un esqueleto de publicación en Codepen y logré escribir algo de JavaScript que haría exactamente esto. Sin embargo, cuando intenté agregarlo en un decorador de publicaciones y hacerlo funcionar en vivo con la API, me topé con un muro.
Esto es lo que tengo en common>header ahora mismo:
<script type="text/discourse-plugin" version="0.8">
api.decorateCookedElement(
element => {
// find the characterpost tag within the post
const characterPost = element.querySelector('[data-wrap="characterpost"]');
// find the parent of the characterpost tag, which contains avatar and username
const characterPostParent = characterPost.closest('article');
// turn it red to see if it's working
characterPostParent.style.backgroundColor = "red";
},
{
id: 'render-character-post', onlyStream: true, afterAdopt: true
}
);
</script>
Esto ha estado lanzando un error. ¿Es posible acceder al envoltorio «article» de las publicaciones usando decorateCookedElement para que pueda obtener el nombre de usuario y el avatar? Si no, ¿cómo puedo abordarlo?
¡Me encontré con esta publicación y pensé que podría intentarlo!
Aquí está la primera versión; espero que el código no sea demasiado horrible.
No probé exhaustivamente todos los casos extremos. Es un punto de partida.
Formato de envoltura esperado: [wrap=character avatar=\"<URL>\"]<Nombre>[/wrap]
Asegúrate de que haya una línea vacía debajo de [wrap]
Puedes personalizar el nombre del personaje con CSS (consulta las clases character y character-extra)
Avísame si tienes algún problema
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>
¡Esto es muy genial, gracias por compartir! Yo también estaba buscando algo similar. ¿Sabes si esto también afecta cómo aparecen las publicaciones en la búsqueda?
¡Buena pregunta! El nombre de la etiqueta y su contenido forman parte del contenido de la publicación; esto podría afectar el resultado de la búsqueda.
Intentaré algo más limpio, como usar una ventana modal y guardar en campos personalizados en su lugar.
EDITAR: Creo que entendí mal si te refieres a que los cambios aparezcan en el resultado de la búsqueda, la respuesta es no (tampoco aparecerá el HTML).
Pensar que podría ser una buena idea proponer, quizás en la wiki de la comunidad, una guía de plantillas de foros. A menudo, la gente busca ideas sobre diferentes tipos de configuraciones de foros. En este caso, podría ser un poco específico. Pero una plantilla de RPG de mesa que incluya esta característica que creaste.