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' }) ); }) ) ); }, }); })();