I’m new to Prosemirror and searching for a way to implement what other editors would call “Templates” or “Widgets”. Basically document elements with a fixed structure and custom rendering. For example, a simple “teaser” widget:
It’s clear how to build this structure in a custom schema, but I since .teaser__image and .teaser__content are representational and might change, I would like to remove them from the result document model:
{
image: "…",
headline: "…",
text: "…"
}
And that’s where I hit a wall. I figured this could be solved by …
Pre-/Post-processing of Prosemirror JSON output
Moving the template into Shadow DOM and use named slots
But both solutions drastically increase complexity, and I wonder if there is a way to solve this with Prosemirror built-in API’s alone or there are existing extensions that solve this.
Your node structure doesn’t have to precisely reflect the HTML structure—as you noticed, you only want actual significant or editable stuff in there. A node can render itself using an HTML structure more complex than just a single element (though some shapes are handled poorly by browsers’ editing implementations), and if you want even more control you can use a node view, which is a bit like a custom component that controls a node’s representation in the editor.
I was looking at node views, but what’s not clear to me is how to control where specific children get rendered to (.teaser__image or .teaser__content). Or perhaps I’m thinking the wrong way about this.
Would it be feasible to separate into the “parent” node view and “child” node views that retrieve their contentDom from “parent”?
Update:
I found this issue which is essentially identical to mine (Multiple holes workaround / nested nodes). Also, based on deeper investigation of prosemirror-view, I think multiple “holes”/“slots” within one node view are not possible.
Yes, each node has one (or no) set of content nodes, you need a parent with a fixed number of children if you want to structure a node to have multiple different pieces of content.