为古腾堡构建特色画廊组件

时间:2020-07-11 作者:leemon

我在建一个Featured Gallery 古腾堡组件。作为指导,我正在使用现有的Featured Image 古腾堡组件。基本上,组件不是存储单个图像id,而是将图像id数组存储在专用的元字段(类型array) 调用_featured_gallery.
显然,获取和设置部分正在工作,但我无法显示所选图像的网格(featured-gallery-grid 代码中的部分)
有什么想法吗?我对古腾堡和React的了解有限,所以我在这里有点迷茫。任何帮助都将不胜感激。

FeaturedGallery:

/**
 * WordPress dependencies
 */
const { __ } = wp.i18n;
const {
    BaseControl,
    Button,
    withNotices,
} = wp.components;
const { compose } = wp.compose;
const { withSelect, withDispatch } = wp.data;
const { MediaUpload, MediaUploadCheck }  = wp.blockEditor;

/**
 * Internal dependencies
 */

import GalleryImage from \'./gallery-image\';

const ALLOWED_MEDIA_TYPES = [ \'image\' ];

function FeaturedGallery( {
    currentPostId,
    featuredGalleryIds,
    onUpdateGallery,
    noticeUI,
} ) {
    const instructions = (
        <p>
            { __(
                \'To edit the featured gallery, you need permission to upload media.\', \'my-featured-gallery\'
            ) }
        </p>
    );

    return (
        <BaseControl
            className="my-featured-gallery"
        >
            { noticeUI }
            <div className="editor-post-featured-gallery">
                <MediaUploadCheck fallback={ instructions }>
                    <div className="editor-post-featured-gallery__container">
                        { !! featuredGalleryIds && (
                            <ul className="featured-gallery-grid">
                            { featuredGalleryIds.forEach( ( img, index ) => {
                                <li>
                                    <GalleryImage
                                        id={ img }
                                    />
                                </li>
                            } ) }
                            </ul>
                        ) }
                    </div>
                    <MediaUpload
                        title={ __( \'Featured gallery\', \'my-featured-gallery\' ) }
                        multiple
                        onSelect={ onUpdateGallery }
                        allowedTypes={ ALLOWED_MEDIA_TYPES }
                        render={ ( { open } ) => (
                                <Button
                                    onClick={ open }
                                    isSecondary
                                >
                                    { 
                                        __( \'Add gallery images\', \'my-featured-gallery\' )
                                    }
                                </Button>
                        ) }
                        value={ featuredGalleryIds }
                    />
                </MediaUploadCheck>
            </div>
        </BaseControl>            
    );
}

const applyWithSelect = withSelect( ( select ) => {
    const { getPostType } = select( \'core\' );
    const { getCurrentPostId, getEditedPostAttribute } = select(
        \'core/editor\'
    );
    const meta = getEditedPostAttribute( \'meta\' );
    const featuredGalleryIds = meta._featured_gallery;

    return {
        currentPostId: getCurrentPostId(),
        postType: getPostType( getEditedPostAttribute( \'type\' ) ),
        featuredGalleryIds,
    };
} );

const applyWithDispatch = withDispatch( ( dispatch ) => {
        const { editPost } = dispatch( \'core/editor\' );
        return {
            onUpdateGallery( images ) {
                const items = images.map( ( item ) => item[\'id\'] );
                const meta = { _featured_gallery: items };
                editPost( { meta } );
            },
        };
    }
);

export default compose(
    withNotices,
    applyWithSelect,
    applyWithDispatch,
)( FeaturedGallery );

GalleryImage:

/**
 * WordPress dependencies
 */
const { withSelect } = wp.data;
const { compose } = wp.compose;

/**
 * Internal dependencies
 */

function GalleryImage( {
    id,
    image
} ) {

    return (
        <figure>
            { image && ( <div className="img-container">
                <img
                    src={ image.media_details.sizes.thumbnail.source_url }
                    width={ image.media_details.sizes.thumbnail.width }
                    height={ image.media_details.sizes.thumbnail.height }
                    alt={ __( \'Thumbnail of the image.\', \'my-featured-gallery\' ) }
                    style={ {
                        display: \'block\',
                        marginBottom: \'8px\',
                    } }
                />
            </div> ) }
        </figure>
    );

}

const applyWithSelect = withSelect( ( select, ownProps ) => {
    const { getMedia } = select( \'core\' );
    const { id } = ownProps;
    return {
        image: id ? getMedia( parseInt( id, 10 ) ) : null,
    };
} );
    
export default compose( [
    applyWithSelect
] )( GalleryImage );

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

在您的GalleryImage

const { withSelect } = wp.data;
const { compose } = wp.compose;

// You should define __
const { __ } = wp.i18n;

在您的FeaturedGalleryreturn 元素,and 设置akey 对于元素(它是一个列表项):(我还删除了index 因为它没有被使用。。如果我们定义一个变量,应该使用它。:)

因为应该返回一个元素,所以应该使用map() 因为forEach() 不返回任何内容,只对数组中的每个元素应用一个函数。

{ featuredGalleryIds.map( ( img ) => {
    return (
        <li key={ img }>
            <GalleryImage
                id={ img }
            />
        </li>
    );
} ) }
备用/更简单的版本-这与上面的基本相同,但如果您想在return 生产线:

{ featuredGalleryIds.map( ( img ) => (
    <li key={ img }>
        <GalleryImage
            id={ img }
        />
    </li>
) ) }
applyWithDispatch(), 你应该使用点符号(item.id) 而不是数组符号(item[\'id\']).

const items = images.map( ( item ) => item.id );    // like this
const items = images.map( ( item ) => item[\'id\'] ); // not this