wordpresswordpress-gutenberggutenberg-blocks

How I Add Srcset to an Image from a Custom Gutenberg Block?


I'm trying to create my own custom gutenberg block to upload images and content, but I'm not able to configure srcset for uploaded image.

In some places it is said that Wordpress adds the srcset automatically, but that was not the case for me when I load the code below it saves everything correctly, but the image is left without the srcset.

I'm trying to create a plugin using the codes posted here, I've searched a lot and haven't found anything about srcset to Custom Gutenberg Block.

block.js

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "dt-panphagia/dt-panphagia",
    "version": "0.1.0",
    "title": "Panphagia",
    "category": "widgets",
    "icon": "admin-site-alt",
    "description": "",
    "keywords": [ "dt", "saurus", "archive" ],
    "supports": {
        "align": ["full", "wide"]
    },
    "textdomain": "dt-panphagia",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": "file:./style-index.css",
    "viewScript": "file:./view.js",
    "attributes": {
        "content": {
            "type": "string",
            "selector": "p"
        },
        "heading": {
            "type": "string"
        },
        "mediaId": {
            "type": "number",
            "default": 0
        },
        "mediaUrl": {
            "type": "string",
            "default": ""
        }
    }
}

edit.js

import { __ } from '@wordpress/i18n';

import { 
    useBlockProps, RichText, MediaUpload, MediaUploadCheck, InspectorControls
} from '@wordpress/block-editor';

import {
    TextControl, ToggleControl, PanelBody, PanelRow, Button, ResponsiveWrapper,
    __experimentalHStack as HStack
} from '@wordpress/components';

import { 
    Fragment 
} from '@wordpress/element'

import './editor.scss';

export default function Edit({ attributes, setAttributes, className }) {

    const blockProps = useBlockProps();

    const removeMedia = () => {
        setAttributes({
            media: ""
        });
    }

    return (
        <Fragment>
            <InspectorControls>
                <PanelBody title={__('Imagem/Achievement', 'dt-panphagia')} initialOpen={ true }>
                    <div className="editor-post-featured-image">
                        <div className='editor-post-featured-image__container'>
                        <MediaUploadCheck>
                            <MediaUpload
                                onSelect = {(media) => {
                                    setAttributes({
                                        mediaId: media['id'],
                                        mediaUrl: media['url'],
                                        mediaWidth: media['width'],
                                        mediaHeight: media['height']
                                    });
                                }}
                                type = "image"
                                value = {attributes.mediaId}
                                render = {({ open }) => {
                                    return (
                                        <Button
                                            className = {attributes.mediaId == 0 ? 'editor-post-featured-image__toggle' : 'editor-post-featured-image__preview'}
                                            onClick = {open}
                                        >
                                        {attributes.mediaId == 0 && __('Escolha uma Imagem', 'dt-panphagia')}
                                        {attributes.mediaId != 0 &&
                                                <ResponsiveWrapper naturalWidth={ attributes.mediaWidth } naturalHeight={ attributes.mediaHeight }>
                                                    <img src={attributes.mediaUrl} />
                                                </ResponsiveWrapper>
                                        }
                                        </Button>
                                    );
                                }}
                            />
                        </MediaUploadCheck>
                        {attributes.mediaId != 0 &&
                        <HStack className='editor-post-featured-image__actions'>
                            <Button className='editor-post-featured-image__action' onClick={removeMedia}>{__('Remove', 'dt-panphagia')}</Button>
                            <MediaUploadCheck>
                                <MediaUpload
                                    title={__('Replace image', 'awp')}
                                    value={attributes.mediaId}
                                    onSelect = {(media) => {
                                        setAttributes({
                                            mediaId: media['id'],
                                            mediaUrl: media['url'],
                                            mediaWidth: media['width'],
                                            mediaHeight: media['height']
                                        });
                                        {console.log(media);}
                                    }}
                                    type = "image"
                                    render = {({open}) => (
                                        <Button className='editor-post-featured-image__action' onClick={open}>{__('Replace', 'dt-panphagia')}</Button>
                                    )}
                                />
                            </MediaUploadCheck>
                        </HStack>
                        }
                        </div>
                    </div>
                </PanelBody>
            </InspectorControls>
            <div {...blockProps} className='achievement'>
                <div className='achievement-wrap'>
                    <div className='achievement-image'>
                        <img
                            className="eb-feature-list-img"
                            src={attributes.mediaUrl} width="54"
                            alt=""
                        />
                    </div>
                    <div className='achievement-content'>
                        <RichText
                            tagName="h3"
                            value={ attributes.heading }
                            allowedFormats={ [ 'core/bold', 'core/italic' ] }
                            onChange={ ( heading ) => setAttributes( { heading } ) }
                            placeholder="Enter heading here..."
                        />
                        <RichText
                            tagName="p"
                            value={ attributes.content }
                            allowedFormats={ [ 'core/bold', 'core/italic' ] }
                            onChange={ ( content ) => setAttributes( { content } ) }
                            placeholder="Button text..."
                        />
                    </div>
                </div>
            </div>
        </Fragment>
    );
}

save.js


import { useBlockProps, RichText} from '@wordpress/block-editor';

export default function save( { attributes } ) {
    const blockProps = useBlockProps.save();
    return (
        <div {...useBlockProps.save()} className='achievement'>
            <div className='achievement-wrap'>
                <div className='achievement-image'>
                    <img
                        className="eb-feature-list-img"
                        src={attributes.mediaUrl} width="54"
                        alt=""
                    />
                </div>
                <div className='achievement-content'>
                    <RichText.Content tagName="h3" value={ attributes.heading } />
                    <RichText.Content tagName="p" value={ attributes.content } />
                </div>
            </div>
        </div>
    );
}

Solution

  • After much search and reading the solution found is almost obvious. So that WordPress loads the srcset of an image just pass a class CSS to this image containing wp-image-{mediaid}.

    ...
    <img
        className={'achievement-image wp-image-' + attributes.mediaId}
        src={attributes.mediaUrl} width={64} height={64}
        alt={attributes.mediaAlt}
    />
    ...