How to handle custom attributes?
Closed this issue · 5 comments
I need to wrap text elements with custom blots that has a specific attribute.
The ops:
{
"ops": [
{
"attributes": {
"spoiler": true
},
"insert": "Testing spoiler tags"
},
{
"insert": ". ignore this\n"
}
]
}
What it currently outputs:
<p>Testing spoiler tags. ignore this</p>
What i want it to output
<p><spoiler>Testing spoiler tags</spoiler>. ignore this</p>
I'm also running into trouble regarding this and wondering it there's a bug somewhere. insert
s with a type
work just fine:
"insert": {
"customemoji": {
"text": ":heart:"
}
}
// Custom converter for custom emoji
if (customOp.insert.type === 'customemoji') {
const emojiText = customOp.insert.value.text;
return emojiText;
}
but attributes don't seem to be caught at all:
{
"insert": "\n",
"attributes": {
"horizontalrule": true
}
},
// Custom converter for Slack horizontal rule
if (customOp. attributes.horizontalrule) {
return '<hr>';
}
Any info on this (even advice on how to debug, add logs, etc) would be great! Thanks!
@dasmikko
I think best way to handle your custom attributes is to make the op a custom blot.
So, in your case, converting your op to this:
{
"ops": [
{
"attributes": {
},
"insert": {"spoiler": "Testing spoiler tags"}
},
{
"insert": ". ignore this\n"
}
]
}
and then rendering your custom blot via this:
converter.renderCustomWith((op, ctxop) => {
if (op.insert.type === 'spoiler') {
return `<spoiler>${op.insert.value}</spoiler>`;
}
})
would give your desired output.
@vahaknp
This op:
{
"insert": "\n",
"attributes": {
"horizontalrule": true
}
},
cannot be converted with .renderCustomWith
because it is not a custom op.
For it to be a custom op, insert
property's value must be an object with just one key and key name cannot be one of the built-in types (which are image
, video
, formula
).
So, you can rewrite that op as a custom op like this:
{
"insert": {"horizontalrule": true},
"attributes": {
}
},
then, you can render it with this:
converter.renderCustomWith((op, ctxop) => {
if (op.insert.type === 'horizontalrule') {
return `<hr>`;
}
})
which will output a result like this: <p><hr></p>
and if you don't want the <p>
tag around the hr
, then you can do this:
converter.afterRender((group, html) => {
if (html === '<p><hr></p>') {
return '<hr>';
}
return html;
});
You are welcome. Sorry for the delay