Writing a Custom Block for Block Editor

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

 

 

 

 

Leave the first comment