Search code examples
wordpresswordpress-gutenberg

Persistently apply format using (start and end index) range in WordPress Gutenberg block


I am working on a Gutenberg sidebar plugin which does some text analysis and based on that, it needs to annotate text in the paragraph blocks. This is the easier part and is achieved using the Annotations API by iterating over each block like this:

wp.data.dispatch( 'core/annotations' ).__experimentalAddAnnotation( {
    source: "my-annotations-plugin",
    blockClientId: wp.data.select( 'core/editor' ).getBlockOrder()[0],
    richTextIdentifier: "content",
    range: {
        start: 50,
        end: 100,
    },
} );

Now, the challenge that I am facing is persisting these annotations (as that's the requirement of the plugin). I figured out that Annotations API internally uses applyFormat method of @wordpress/rich-text package but I am not able to figure out how to use applyFormat directly. The documentation is in-adequate and lacks code examples.

If you have worked with this it would help to have sample working (ES5 or ES6) code to use applyFormat in the right way.


Solution

  • I finally figured it out. Just posting it here if anyone needs to do this as the Gutenberg documentation lacks code examples.

    With reference to the below code, blockIndex is the block you are dealing with; and startIndex and endIndex are ranges to annotate in context of the block:

    // Get latest modified content of the block
    let html = wp.data.select( "core/editor" ).getBlocks()[blockIndex].attributes.content;
    // Get uuid of the block
    let blockUid = wp.data.select( "core/editor" ).getBlocks()[blockIndex].clientId;
    // Create a RichText value from HTML string of block content
    let value = wp.richText.create({
      html
    });
    // Apply a format object to a Rich Text value from the given startIndex to the given endIndex
    value = wp.richText.applyFormat(value, { type: 'strong' }, startIndex, endIndex);
    // Update the block with new content
    wp.data.dispatch( 'core/editor' ).updateBlock( blockUid, {
        attributes: {
          content: wp.richText.toHTMLString({
            value
          })
        }
      } );