Need help with custom WP Block. The block allows user to add an image, text, and ability to have inner blocks to include rich content.
While everything saves and works, the InnerBlocks content is lost upon refresh. Additionally, the InnberBlocks does not render on front end.
This is the JS:
wp.blocks.registerBlockType('gpe/media-text', {
apiVersion: 2,
title: 'Media-Text', // Block name visible to the user within the editor
icon: 'warning', // Toolbar icon displayed beneath the name of the block
category: 'common', // The category under which the block will appear in the Add block menu
attributes: { // The data this block will be storing
image_id : { type : 'number', default : -1 },
image_name : { type : 'string', default: ""},
image_url: { type: 'string' , selector : 'sc-media-upload-image'}, // Notice box type for loading the appropriate CSS class. Default class is 'default'.
image_text: { type: 'string' },
text_content: { type: 'string' }, // Title of Notice box in h4 tag
inner_content : { type: 'string'},
},
edit: function(props) {
// Defines how the block will render in the editor
//const [ isChecked, setChecked ] = useState( true )
return el( 'div',
useBlockProps ({
className: 'media-text' ,
style : {
}
}),
el( InnerBlocks , { onChange : function(a){console.error(a); } } ) ,
el(
TextControl ,
({
//type: 'text',
placeholder: 'Section title',
value: props.attributes.text_content,
onChange: (value) => {
props.setAttributes({ text_content: value })
},
style: {
}
})
),
el (MediaUpload ,
{
value: props.attributes.image_url,
allowedTypes: ['images'],
labels: { title : 'Select Feature Image' },
multiple: false,
onSelect: function(media){
console.error ("DEBUG>>", media, "Attributes", props.attributes);
props.setAttributes({
image_url: media.url,
image_name : media.filename,
image_text : media.title
})
},
render: function ({ open }){
return el("div",{},
el ('img', { src : props.attributes.image_url , width: 200+'px', height: '200px' , onClick : open })
)
}
}
),
); // End return
}, // End edit()
save: function(props) {
return null;
} // End save()
});
This is the render_callback:
register_block_type( 'gpe/media-text', array(
'render_callback' => 'jst_block_media_text_render',
'api_version' => 2,
'editor_script' => 'slb-script', //this name must match with wp_register_script - script name
'editor_style' => 'slb-style',
) );
function jst_block_media_text_render ( $attr, $content ) {
$out = '<div class="flex media-text gpe">' .
'<img src="'. $attr['image_url'] . '">'.
'<div class="content">'.
$content .
' - content </div>'.
'</div>' ;
return $out;
}
Below you will find a working solution. I have stripped out any non-relevant things. Please note that this posted code is not tested.
import {InnerBlocks, useBlockProps} from '@wordpress/block-editor';
import {registerBlockType} from '@wordpress/blocks';
registerBlockType('urukai/example', {
apiVersion: 2,
title: 'An Example Block',
category: 'common',
description: 'An example block with inner blocks',
icon: 'carrot',
edit() {
const p = useBlockProps({
className: 'u-block u-example-block'
});
return (
<div {...p}>
<div className="text-content-container">
<InnerBlocks
allowedBlocks={ [ 'core/heading', 'core/paragraph', 'core/list' ] }
template={ [
[ 'core/heading', { placeholder: 'Example Title...' } ],
[ 'core/paragraph', { placeholder: 'Examplte text goes here...' } ]
]}
/>
</div>
</div>
);
},
save() {
return <div className="your-container-class"><InnerBlocks.Content/></div>;
}
});
Hope this helps.