Trying to replace / auto-format strings in user posts

AI-generated summary

A user, hemes, is seeking to auto-format strings in user posts to display game state as a table. Arkshine points out the possibility of achieving this using the decorateCookedElement API. hemes confirms that this is the solution needed and shares a helpful example of filtering elements using api.decorateCooked. This example uses a custom function to target specific elements and perform actions on them. The solution involves firing scripts after topic HTML is rendered in the DOM.

Hello, I am new to Discourse and have my site up and am trying to get a critical piece of functionality I need for a major portion of the community figured out.

Users have software that can export magic strings that represent some game state and I want to render that state nicely as a table that gets generated from the string (at page load time).

Ideally, I give users a template when posting or they put their magic string inside a named class or something and the string just gets rendered (decorated?) at page load time.

Can I do this? I am currently thinking I should write a script that parses the strings for all elements/classes of that type but am struggling on how/when to get the script to modify the displayed (cooked?) post.

Thanks,
Brett

Sure, it should be possible. You have an API to decorate the cooked post.
For example: decorateCookedElement

Can you share a visual example of exactly what you’re trying to achieve?

Maybe you can create your own style

All right! It seems that decorateCookedElement is what I needed (per @Arkshine note).

I also found this post that has some nice examples to filter on elements of interest:
How do we fire scripts after topic HTML is rendered in DOM? - dev - Discourse Meta

In particular, I found this very helpful:

$.fn.doSomething = function() {
  const targetElement = $(this).children("[data-theme-test]").length;
  if (!targetElement) return;

  // do your work
  
  return this;
};

api.decorateCooked($elem => $elem.doSomething(), { onlyStream: true });

Thank you!