Block Validation Fails: '<' in HTML content escaped by save function

I have some custom blocks. Each has a save function that gets content from the block's attributes:( { className, a

I have some custom blocks. Each has a save function that gets content from the block's attributes:

( { className, attributes } ) => (
    <div className = { className }>{ attributes.content }</div>
)

Here is the configuration of the content attribute:

attributes: {
    content: {
        source: "html",
        type: "string",
        selector: "div"
    }
}

The content is an object, namely, a React component. The content renders as expected in the block editor. When I preview the post, it renders as expected on the front end—likewise when I view it after publishing.

But when I go to edit the saved post, block validation fails. The error message shows that the "Content generated by 'save' function" escapes the < in the HTML content from attributes, whereas the "Content retrieved from post body" does not.

Say the retrieved content is this:

<div class="wp-block-example-class"><p>Example paragraph</p></div>

Then the saved content is this:

<div class="wp-block-example-class">&lt;p>Example paragraph&lt;/p></div>

I found this support post about a similar problem solved by using RawHTML. So I tried changing my save function:

( { className, attributes } ) => (
    <div className = { className }>
        <RawHTML>{ renderToString( attributes.content) }</RawHTML>
    </div>
)

I got the same results described above. Note that I first tried using RawHTML without renderToString—that is, <RawHTML>{ attributes.content }</RawHTML>. The content rendered as expected in the editor but not on the front end, where the block's div wrapper contained the text "undefined" and "null" where elements derived from React components should have been.

In case it matters, the blocks are created and inserted programmatically. Simplified, here is the process:

const myContent = ( <MyComponent>{"Some content"}</MyComponent> );
const myBlock   = createBlock( "example/my-block", {  
    content: myContent 
} );

dispatch( "core/block-editor" ).insertBlock( myBlock );

What might I try to prevent < from being escaped by the block's save function?

I have some custom blocks. Each has a save function that gets content from the block's attributes:

( { className, attributes } ) => (
    <div className = { className }>{ attributes.content }</div>
)

Here is the configuration of the content attribute:

attributes: {
    content: {
        source: "html",
        type: "string",
        selector: "div"
    }
}

The content is an object, namely, a React component. The content renders as expected in the block editor. When I preview the post, it renders as expected on the front end—likewise when I view it after publishing.

But when I go to edit the saved post, block validation fails. The error message shows that the "Content generated by 'save' function" escapes the < in the HTML content from attributes, whereas the "Content retrieved from post body" does not.

Say the retrieved content is this:

<div class="wp-block-example-class"><p>Example paragraph</p></div>

Then the saved content is this:

<div class="wp-block-example-class">&lt;p>Example paragraph&lt;/p></div>

I found this support post about a similar problem solved by using RawHTML. So I tried changing my save function:

( { className, attributes } ) => (
    <div className = { className }>
        <RawHTML>{ renderToString( attributes.content) }</RawHTML>
    </div>
)

I got the same results described above. Note that I first tried using RawHTML without renderToString—that is, <RawHTML>{ attributes.content }</RawHTML>. The content rendered as expected in the editor but not on the front end, where the block's div wrapper contained the text "undefined" and "null" where elements derived from React components should have been.

In case it matters, the blocks are created and inserted programmatically. Simplified, here is the process:

const myContent = ( <MyComponent>{"Some content"}</MyComponent> );
const myBlock   = createBlock( "example/my-block", {  
    content: myContent 
} );

dispatch( "core/block-editor" ).insertBlock( myBlock );

What might I try to prevent < from being escaped by the block's save function?

Share Improve this question asked Jun 21, 2020 at 2:11 rsbornrsborn 315 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I solved the problem by rendering my block's content, a component, to a string and making that string the value of a RichText component in my block's save function.

To make my component a string, I used renderToString:

// Create the content and the block
const myContent = ( <MyComponent>{"Some content"}</MyComponent> );
const myBlock   = createBlock( "example/my-block", {  
    content: renderToString( myContent )
} );

And here is my block's save function:

( { className, attributes } ) => (
    <RichText.Content 
        tagName   = 'div'
        className = { className }
        value     = { attributes.content }
    />
)

I tried this solution since I have other custom blocks that use RichText, and those blocks weren't having an issue with unwanted escaping. But I don't know why I needed to use RichText for the blocks that were having an issue. The content of the affected blocks is generated automatically and contains no formats, core or custom.

One last note. The "undefined" and "null" that appeared in my block's wrapper on the front end when using <RawHTML>{ attributes.content }</RawHTML> in my block's save function resulted from a front end script, not anything related to the block editor. My block's save function was actually generating nothing inside the block wrapper.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742329135a4423353.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信