Example of how we can write a custom block for the block editor.
In this example, there is a gallery block added. By using this block you can add multiple images in the same block. There is CSS issues because I didn’t care how it looks. Didn’t have a chance to use this on a client project yet. I usually refine my codes when I use it on client sites 🙂
Anyway it is a very simple example have fun with it.
To register your block first write your PHP register function in your functions.php
function your_theme_enqueue_block_editor_assets3() {
wp_enqueue_script(
'your-image-gallery-block',
get_template_directory_uri() . '/blocks/your-image-gallery-block.js',
array('wp-blocks', 'wp-block-editor', 'wp-element', 'wp-components', 'wp-media-utils', 'wp-i18n'),
filemtime(get_template_directory() . '/blocks/your-image-gallery-block.js')
);
}
add_action('enqueue_block_editor_assets', 'your_theme_enqueue_block_editor_assets3');
and put your your-image-gallery-block.js file in the /blocks directory under your theme.
(function () {
var registerBlockType = wp.blocks.registerBlockType;
var MediaUpload = wp.blockEditor.MediaUpload;
var useBlockProps = wp.blockEditor.useBlockProps;
var createElement = wp.element.createElement;
var Button = wp.components.Button;
registerBlockType('your-theme/image-gallery-block', {
title: 'Image Gallery Block2',
description: 'Add an image gallery',
icon: 'format-gallery',
category: 'common',
attributes: {
images: {
type: 'array',
default: [],
},
},
edit: function (props) {
var blockProps = useBlockProps();
var onAddImage = function (image) {
var updatedImages = props.attributes.images.concat(image);
props.setAttributes({ images: updatedImages });
};
var onRemoveImage = function (index) {
var updatedImages = props.attributes.images.filter(function (_, i) {
return i !== index;
});
props.setAttributes({ images: updatedImages });
};
return createElement(
'div',
blockProps,
createElement(
'ul',
{ className: 'image-gallery' },
props.attributes.images.map(function (image, index) {
return createElement(
'li',
{ key: index },
createElement('img', { src: image.url, alt: 'Image' }),
createElement(
Button,
{
className: 'remove-image-button',
onClick: function () {
onRemoveImage(index);
},
},
'Remove'
)
);
})
),
createElement(
MediaUpload,
{
onSelect: onAddImage,
allowedTypes: ['image'],
multiple: true,
gallery: true,
value: props.attributes.images.map(function (image) {
return image.id;
}),
render: function (obj) {
return createElement(
Button,
{
onClick: obj.open,
className: 'add-image-button',
},
'Add Images'
);
},
}
)
);
},
save: function (props) {
var blockProps = useBlockProps.save();
return createElement(
'div',
blockProps,
createElement(
'ul',
{ className: 'image-gallery' },
props.attributes.images.map(function (image, index) {
return createElement(
'li',
{ key: index },
createElement('img', { src: image.url, alt: 'Image' })
);
})
)
);
},
});
})();