WordPress Gutenberg 自定义图像块无法识别 src

WordPress Gutenberg Custom Image Block doesn't recognize src

这是我第一个使用 <img> 标签的 Wordpreess Gutenberg 块。我似乎无法显示图像。文本呈现但图像 src 似乎不起作用。当我打开 DOM 并检查元素时,<img> 标记位于 DOM 树中,但没有 src 它只是空的。我试过将 <Media Upload> 放在行内和 <Panel Body> 中,但无论哪种方式 <img src> 都没有采用。我确定我忽略了一些东西,但经过反复试验,我似乎无法将 <Media Upload> 正确连接到图像源。

const { registerBlockType } = wp.blocks;
const { 
    RichText, 
    InspectorControls, 
    ColorPalette,
    MediaUpload,
    MediaUploadCheck,
    Button,
    RawHTML,
    InnerBlocks
} = wp.editor;

const { PanelBody, IconButton } = wp.components;
const ALLOWED_BLOCKS = ['core/button', 'core/html', 'core/image']
registerBlockType('mycustomblock/feature-block', {
    //Built-in Attributes
    title: 'Feature Block',
    description: 'Block Description',
    icon: 'align-pull-left',
    category: 'design',

    //Custom Attributes
    attributes: {
        title: {
            type: 'string',
            source: 'html',
            selector: 'p'
        },
        titleColor: {
            type: 'string',
            default: 'black'
        },
        bodyColor: {
            type: 'string',
            default: 'black'
        },
        image: {
            type: 'object',
            source:'html',
            selector:'feature-icon'
        },
        body: {
            type: 'string',
            source: 'html',
            selector: 'p'
        }
    },

    //Built-in Functions
    edit({attributes, setAttributes}) {
        const{
            title,
            body,
            titleColor,
            bodyColor,
            image,
        } = attributes;

        //Custom Functions
        
        function onChangeTitle(newTitle) {
            setAttributes( { title: newTitle } );
        }

        function onChangeBody(newBody) {
            setAttributes( { body: newBody } );
        }

        function onTitleColorChange(newColor){
            setAttributes( { titleColor: newColor } );
        }

        function onBodyColorChange(newBodyColor){
            setAttributes( { bodyColor: newBodyColor } );
        }

        function onSelectImage(newImage) {
            setAttributes( { image: newImage.sizes.full.url } )
        }

        return ([
            <InspectorControls style={ { marginBottom: '40px' } }>
                {/* <PanelBody title={ 'Image Settings' }>
                    
                </PanelBody> */}

                <PanelBody title={ 'Headline Color' }>
                    <p><strong>Choose Title Color</strong></p>
                    <ColorPalette 
                        value={titleColor} 
                        onChange={onTitleColorChange} 
                    />
                </PanelBody>

                <PanelBody title={ 'Description Color' }>
                    <p><strong>Choose Description Color</strong></p>
                    <ColorPalette 
                        value={bodyColor} 
                        onChange={onBodyColorChange} 
                    />
                </PanelBody>
            </InspectorControls>,

        <div class="row">
            <div class="col-md-4"> 
                <div class="feature-icon-container">
                    <MediaUpload 
                            onSelect={onSelectImage}
                            type="image"
                            value={image}
                            render={ ( { open } ) =>
                                <IconButton
                                    onClick={ open }
                                    icon="upload"
                                    className="editor-media-placeholder__button is-button is-default is-default"
                                >
                                    Select Image
                                </IconButton>
                            }
                        />  
                </div>
                <div class="feature-description-container">
                    <RichText 
                            key="editable"
                            tagName="p"
                            placeholder="Feature Title" 
                            value= { title }
                            onChange= { onChangeTitle }
                            style= { { color: titleColor } }
                        />
                        <RichText 
                            key="editable"
                            tagName="p"
                            placeholder="Description" 
                            value= { body }
                            onChange= { onChangeBody }
                        />
                </div>
            </div>
        </div>
        
        ]);
    },

    save({ attributes }) {
        const {
            title,
            body,
            titleColor,
            bodyColor,
            image,
        } = attributes;
        return(
        <div class="row">
            <div class="col-md-4">
                    <div class="feature-image-container">
                        <img class="feature-icon" src={ { image } } />
                    </div>
                    <div class="feature-description-container">
                        <RichText.Content style={ {color:titleColor } } tagName="p" value={title} />
                        <RichText.Content style={ {color:bodyColor } } tagName="p" value={body} />
                    </div>
                
                </div>
        </div> 
        ) 
    }
});

有几处我们需要更正,我会为您指出正确的方向:

  1. 关于如何“获取”image 属性的小误解。您正在从 MediaUpload 组件获取图像的 src 并通过 onSelectImage 函数设置 image 属性(这是一个 URL 字符串)。在您现在声明它的方式中,您尝试从 html selector 的 innerHTML 获取它。 因此,在您的属性声明中使用以下语法就​​足够了:
image: {
   type: 'string',
   default: '',
}

如果需要,您可以插入 default/placeholder 图片的 src url 而不是空字符串。

并且只是想让你知道:从 html selector 采购只有当 selector 的 innerHTML 在块的内容中是可编辑的时候才有意义,比如一个可编辑的富文本组件(即段落)。

  1. 您需要 edit 中的一些逻辑才能在 selected 后在后端实际显示图像。下面只是一个简单的版本,需要进一步优化(因为你不能 select 这样的另一个图像)。 将 edit 中的完整 <div class="feature-icon-container"></div> 结构替换为:
<div class="feature-image-container">
{ image === '' ?
      <MediaUpload 
         onSelect={onSelectImage}
         type="image"
         value={image}
         render={ ( { open } ) =>
             <IconButton
             onClick={ open }
             icon="upload"
             className="editor-media-placeholder__button is-button is-default is-default">
              Select Image
              </IconButton>
         }
     />
:
<img class="feature-icon" src={ image } />
</div>
  1. save 中的双 curly 大括号更改为单 curly 大括号。否则你的 URL 字符串将被包裹在一个对象中。
<img class="feature-icon" src={ image } />

也许最好将 MediaUpload 移动到控件侧边栏,这样更容易保留更改 selected 图像的功能。此外,如果您设置默认图像,则无法将您的条件基于检查空 image 字符串。但我会把这个留给你。