Writer marks/nodes
The Writer is our rich-text editor powering the writer field and list field but also the text and heading blocks, among others. In your plugin, you can add custom marks and nodes to enhance and customize the editing experience of those fields and blocks.
The Writer is built on top of ProseMirror. When diving deeper into your project, you will probably also need to consult the ProseMirror documentation for all details.
Custom marks
A mark is a "a piece of information that can be attached to a node, such as it being emphasized, in code font, or a link" – e.g. our default marks include bold, strike, sub, sup etc.
A custom mark automatically extends our JavaScript Mark
class that functions as thin layer over the raw ProseMirror implementation. You can start building your mark from there:
You can also take a look at the implementation of the default marks as well as ProseMirror's mark docs.
Custom nodes
A node represents some structured content in ProseMirror's document tree. Often this is rather seen as blocks, where marks are rather inline. Our default marks include the normal text paragraph, unordered/ordered lists, headings etc.
A custom node automatically extends our JavaScript Node
class that functions as thin layer over the raw ProseMirror implementation. You can start building your node from there:
You can also take a look at the implementation of the default nodes as well as ProseMirror's node docs.
Using custom marks/nodes in your fields
Learn how to activate your custom mark or node. This also works for blocks, when you extend or overwrite e.g. the text blocks' blueprint to add the right options to the block's text field (which is a writer type field by default).
Troubleshooting
Competing with other nodes/mark
When implementing a custom node/mark, your parseDOM
rules might compete with rules from other nodes/marks. E.g. your custom node targets a <p>
tag with a specific class, while the default paragraph node targets all <p>
tags. This can lead to problems, when the broader parseDOM
rule gets checked before the more specific one.
If you run into issues here, you can use the priority
option and choose a value higher than 50 (which is the default) to ensure your parseDOM
rule gets checked first.