将多个图像添加到自定义块

时间:2021-04-16 作者:Cameron

我编写了以下自定义块,允许用户创建一个简单的滑块,并添加一个图像,然后将其包装在滑块项元素中。我选择将其设置为单个块,而不是使用嵌套块(例如滑块项目块和父滑块),因为我不希望在块编辑器中使用其他HTML包装,而是希望它是单个图像块(如gallery块)。

(function(blocks, editor, element, blockEditor, components) {
var el = element.createElement;
var MediaUpload = editor.MediaUpload;

blocks.registerBlockType(\'theme/slider\', {
        title: \'Slider\',
        icon: \'universal-access-alt\',
        category: \'layout\',
        example: {},
        attributes: {
            mediaID: {
                type: \'number\',
            },
            mediaURL: {
                type: \'string\',
                source: \'attribute\',
                selector: \'img\',
                attribute: \'src\',
            },
        },
        edit: function(props) {
            function onSelectImage(media) {
                return props.setAttributes({
                    mediaURL: media.url,
                    mediaID: media.id,
                });
            };

            return el(\'div\', {
                    className: \'slider\'
                },
                el(\'div\', {
                        className: \'slider-item\'
                    },
                    el(MediaUpload, {
                        onSelect: onSelectImage,
                        allowedTypes: \'image\',
                        value: props.attributes.mediaID,
                        render: function(obj) {
                            return el(
                                components.Button, {
                                    className: props.attributes.mediaID ?
                                        \'image-button\' :
                                        \'button button-large\',
                                    onClick: obj.open,
                                },
                                !props.attributes.mediaID ?
                                \'Upload Image\' :
                                el(\'img\', {
                                    src: props.attributes.mediaURL
                                })
                            );
                        },
                    }),
                }),
        );
    },
    save: function(props) {
        return el(\'div\', {
                className: \'slider\'
            }, el(\'div\', {
                className: \'slider-item\'
            }, (props.attributes.mediaURL ? el(\'img\', {
                src: props.attributes.mediaURL
            }) : el(\'div\')))
        },
    });
});
})(window.wp.blocks, window.wp.editor, window.wp.element, window.wp.blockEditor, window.wp.components);
然而,我不知道如何使这两个属性mediaIDmediaURL 可重复?

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

您还需要在代码中进行其他更改,但对于主要的更改mediaIDmediaURL 要可重复(core) gallery block 通过设置query 作为属性源和array 作为属性键入。

因此,我也会这样做,例如,您可以将属性名称设置为images:

// Define the attribute:
attributes: {
    images: {
        type: \'array\',
        source: \'query\',
        selector: \'.slider-item\',
        default: [],

        // The following means in each .slider-item element in the saved markup,
        // the attribute value is read from the data-id or src attribute of the
        // img element in the .slider-item element. And yes of course, you can
        // change the selector to \'a\', \'.some-class\' or something else.
        query: {
            mediaID: {
                type: \'number\',
                source: \'attribute\',
                attribute: \'data-id\',
                selector: \'img\',
            },
            mediaURL: {
                type: \'string\',
                source: \'attribute\',
                attribute: \'src\',
                selector: \'img\',
            },
        },
    },
}

/* And the attribute value would look like:
images: [
  { mediaID: 1, mediaURL: \'https://example.com/wp-content/uploads/2021/04/image.png\' },
  { mediaID: 2, mediaURL: \'https://example.com/wp-content/uploads/2021/04/image2.png\' },
  ...
]
*/
然后在你的MediaUpload 元素,则需要设置gallery and multiple propertiestrue (允许多个图像选择),并在onSelectImage() 函数中,可以设置属性值(它是一个数组),如下所示:

props.setAttributes( {
    images: items.map( item => {
        return {
            mediaID: parseInt( item.id, 10 ),
            mediaURL: item.url,
        };
    } ),
} );

试试我的块/代码,这样它就使用了JSX和ESNext,但是save() 输出与问题中的输出相同,您可以找到代码here. :)

相关推荐