Generic bbcode wrapper for theme components

AI-generated summary

Generic bbcode wrapper for theme components

joffreyjaffeux introduced a feature allowing the use of a special markdown syntax in theme components, eliminating the need for a plugin. The syntax is as follows: [wrap=baz foo=bar]Content[/wrap]. This will render as a div element with a data-wrap attribute and additional data attributes for any properties.

However, lcestou encountered an issue with attribute names containing multiple hyphens, which was later fixed by joffreyjaffeux. The fix supports camelCase attribute names.

4ong asked for guidance on implementing a feature to whitelist specific HTML attributes, such as class and data-item-id, in topics. joffreyjaffeux suggested decorating the wrap in a theme component.

Additionally, sam shared an example of expanding this feature to support generic components using the customblock syntax, which is used in the official Discourse Mermaid theme component.

I added this feature a while back and realised I didn’t post about it. You can now use a special syntax in markdown to have it cooked and usable in theme components without having to write a plugin.

// wrapped in div.d-wrap
[wrap=baz foo=bar]Content[/wrap]

// wrapped in div.d-wrap
[wrap=baz foo=bar]
Content
[/wrap]

// wrapped in div.d-wrap
[wrap=baz foo=bar]
[/wrap]

// this one will be rendered as a span.d-wrap instead of a div.d-wrap
a [wrap=baz]Content[/wrap] b

The name of the component will be added as a data-attribute: data-wrap="baz" and every properties will also be data-attributes: data-foo="bar" on the element.

If you want to read about a real world use case, see

20 Likes

Hello Joffrey,

Thanks for suggesting this feature in the other topic.

I was excited to try to use it and see if it worked for my case, however I encountered a problem.

It seems to ignore attribute names that has multiple hyphens in between and defaults to only pick the characters after the last hyphen.

I am using v2.4.0.beta2 +33, I apologize if this has been fixed in a newer commit since.

Examples:

// No multiple hyphen this works fine: data-bloodmallet="chart".
[wrap=test bloodmallet=chart]Content[/wrap]

// This way it omits "user" from the attribute name and output is data-id="1" instead of data-user-id="1".
[wrap=test2 user-id=1]Content[/wrap]

This following request is optional: Is there a way to not wrap the content inside the div with <p> tag?

Thanks for this feature and hopefully I can use it to fix my problem!

I can fix the first issue

1 Like

I just pushed a fix for this, slight difference is that I won’t support foo-bar but fooBar. So you can now write:

[wrap=foo userId=1]
[/wrap]

And you will get:

<div data-wrap="foo" data-user-id="1">
</div>
5 Likes

Hi @j.jaffeux
Thanks for this feature! Do you know the best direction how to add feature for things like

<button class="snipcart-add-item" data-item-id="product-1" data-item-url="/" data-item-name="Product #1" data-item-price="10.99">
  Add to cart
</button>

in topics. And generally - to whitelist

class="snipcart-add-item" data-item-id="product-1"

Working example - https://codepen.io/thatfrankdev/pen/xxwRXQw

You need to decorate your wrap in a theme component, like we do here for example: discourse-placeholder-theme-component/javascripts/discourse/initializers/setup.js at main · discourse/discourse-placeholder-theme-component · GitHub

4 Likes

@j.jaffeux Thanks for the awesome advice!

Recently we expanded this to support generic components using:

```customblock param=1
```

This will be translated to:

<pre data-code-param="1" data-code-wrap="customblock"><code class="lang-nohighlight"></code></pre>

Thus as a component you can use data-code-wrap to determine special handling and syntax highlighting is disabled.

We used this pattern here:

https://github.com/discourse/discourse-mermaid-theme-component

Which is an official mermaid theme component.

9 Likes