I have a custom Gutenberg block (https://pastebin.com/bV2k5Ekc) in which I display text, link and an image. I want to change it so so instead of saving the image URL as a background image of the container, to use an img tag. Unfortunately - I can't manage to create the deprecation correctly - I fail at assigning the attributes parameters in the deprecation:
From this:
const {
attributes: {
mediaURL,
boxTitle,
boxDescription,
linkText,
linkHref,
linkTitle
},
className,
} = props;
let boxClass = 'cta-box';
let contentDescription = '';
if (boxDescription.length) {
boxClass += ' cta-box-description';
contentDescription = (
<p>
{boxDescription}
</p>
)
}
return (
<div className={`cta-block-box ${className}`}>
<a
className="cta-box-link"
href={linkHref}
style={{ backgroundImage: "url(" + mediaURL + ")" }}
rel="noopener noreferrer"
>
<div className={boxClass}>
<h3>
{boxTitle}
</h3>
{contentDescription}
<span className="arrow">{linkText ? linkText : linkTitle}</span>
</div>
</a>
</div>
);
},
To this (I only change what's in the return statement):
return (
<div className={`cta-block-box ${className}`}>
<a
className="cta-box-link"
rel="noopener noreferrer"
>
<img className="cta-box-image" src={linkHref} alt=""/>
<div className={boxClass}>
<h3>
{boxTitle}
</h3>
{contentDescription}
<span className="arrow">{linkText ? linkText : linkTitle}</span>
</div>
</a>
</div>
);
Which of course broke the Gutenberg element. So I added a deprecate to the blog, as much as I could following the official Wordpress documentation:
deprecated: [
{
attributes: {...this.attributes},
save: (props) => {
const {
attributes: {
mediaURL,
boxTitle,
boxDescription,
linkText,
linkHref,
linkTitle
},
className,
} = props;
console.log('dep');
console.log(props);
let boxClass = 'cta-box';
let contentDescription = '';
if (boxDescription.length) {
boxClass += ' cta-box-description';
contentDescription = (
<p>
{boxDescription}
</p>
)
}
return (
<div className={`cta-block-box ${className}`}>
<a
className="cta-box-link"
style={{ backgroundImage: "url(" + mediaURL + ")" }}
rel="noopener noreferrer"
>
<div className={boxClass}>
<h3>
{boxTitle}
</h3>
{contentDescription}
<span className="arrow">{linkText ? linkText : linkTitle}</span>
</div>
</a>
</div>
);
},
}
],
After this the editor page crashes, and I get error message in console, that attributes is not defined (displaying incorrect row in the script file). This is the "after" script contents (https://pastebin.com/dVdLMx7N).
react-dom.min.js?ver=16.13.1:125 ReferenceError: attributes is not defined
at save (cta-box2.js?f66a:242)
at Wt (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
at Qt (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
at block-editor.min.js?ver=4378547cec8f5157a02ead3dfc5c65b2:12
at hooks.min.js?ver=50e23bed88bcb9e6e14023e9961698c1:2
at $r (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
at blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3
at Ur (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
at blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3
at Array.reduce (<anonymous>)
Any help would be greatly appreciated! I suspect I'm missing some small detail, but so far I've failed to locate it. And was not able to find relevant enough information on the web.
Thanks in advance!
There are two issues in your "after" script:
The attributes do not match (and the this
is actually the window
object): attributes: {...this.attributes}
(see line 212).
So what you used with the attributes
property on line 24, should also be used with the same property on line 212. (because you only changed the output, so the block attributes remain the same)
The save
output/markup also do not match — in the "before" script, you've got href={linkHref}
, but in the deprecated
property of the "after" script, the save
output did not have that href
. (see this diff)
So make sure the attributes and save
output match the ones in the old/"before" script, and the following is how your code would look like, but note that I only included the main parts that need to be fixed:
// Define the attributes and use it with the root "attributes" property and
// the one in the "deprecated" property.
const blockAttributes = {
mediaID: {
type: 'number'
},
mediaURL: {
type: 'string'
},
boxTitle: {
type: 'string',
default: ''
},
// ... the rest of the attributes here.
};
registerBlockType('hswp/test-box', {
title: __('Test Box', 'modula'),
// ... your code.
attributes: blockAttributes,
// ... your code.
deprecated: [
{
attributes: blockAttributes,
save: (props) => {
// ... your code.
return (
<div className={`cta-block-box ${className}`}>
<a
className="cta-box-link"
href={linkHref}
style={{ backgroundImage: "url(" + mediaURL + ")" }}
rel="noopener noreferrer"
>
... your code.
</a>
</div>
);
},
}
],
});
Additionally, note that the PlainText
component doesn't (as of writing) have a property named tagName
.