Ретрансляторы Gutenberg с использованием ESNEXT - PullRequest
3 голосов
/ 14 января 2020

Я работал над созданием своего собственного блока повторителя Гутенберга с полем ввода текста и ссылок. Я видел только образцы ES5, такие как , и , . Я работаю над созданием собственной версии этих образцов уже около 8 часов, и я застрял.

Я здесь, потому что хочу, чтобы меня указали в правильном направлении (очень нужна помощь ).

Вот код, который у меня сейчас есть. Я не знаю, с чего начать преобразование ES5 -> ESNEXT.

Редактировать: я забыл сказать, что я пытаюсь избежать использования ACF для этого

// Importing code libraries for this block
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { RichText, MediaUpload, InspectorControls } from '@wordpress/block-editor';
import { Button, ColorPicker, ColorPalette, Panel, PanelBody, PanelRow } from '@wordpress/components';

registerBlockType('ccm-block/banner-block', {
    title: __('Banner Block'),
    icon: 'format-image', // from Dashicons → https://developer.wordpress.org/resource/dashicons/.
    category: 'layout', // E.g. common, formatting, layout widgets, embed.
    keywords: [
        __('Banner Block'),
        __('CCM Blocks'),
    ],
    attributes: {
        mediaID: {
            type: 'number'
        },
        mediaURL: {
            type: 'string'
        },
        title: {
            type: 'array',
            source: 'children',
            selector: 'h1'
        },
        content: {
            type: 'array',
            source: 'children',
            selector: 'p'
        },
        bannerButtons: {
            type: 'array',
            source: 'children',
            selector: '.banner-buttons',
        },
        items: {
            type: 'array',
            default: []
        }
    },

    /**
     * The edit function relates to the structure of the block when viewed in the editor.
     *
     * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
     *
     * @param {Object} props Props.
     * @returns {Mixed} JSX Component.
     */
    edit: (props) => {

        const {
            attributes: { mediaID, mediaURL, title, content, bannerButtons },
            setAttributes, className
        } = props;

        const onSelectImage = (media) => {
            setAttributes({
                mediaURL: media.url,
                mediaID: media.id,
            });
        };

        const onChangeTitle = (value) => {
            setAttributes({ title: value });
        };

        const onChangeContent = (value) => {
            setAttributes({ content: value });
        };

        const onChangeBannerButtons = (value) => {
            setAttributes({ bannerButtons: value });
        };

        // console.log(items);
        // var itemList = items.sort

        return (
            <div className={className}>
                <div id="#home-banner">
                    <MediaUpload
                        onSelect={onSelectImage}
                        allowedTypes="image"
                        value={mediaID}
                        render={({ open }) => (
                            <Button className={mediaID ? 'image-button' : 'button button-large'} onClick={open}>
                                {!mediaID ? __('Upload Image', 'ccm-blocks') : <img src={mediaURL} alt={__('Featured Image', 'ccm-blocks')} />}
                            </Button>
                        )}
                    />

                    <RichText
                        tagName="h1"
                        placeholder={__('Insert Title Here', 'ccm-blocks')}
                        className={className}
                        onChange={onChangeTitle}
                        value={title}
                    />

                    <RichText
                        tagName="p"
                        placeholder={__('Insert your short description here...', 'ccm-blocks')}
                        className={className}
                        onChange={onChangeContent}
                        value={content}
                    />

                    <RichText
                        tagName="ul"
                        multiline="li"
                        className="banner-buttons"
                        placeholder={ __('Add a banner button link (max of 2)', 'ccm-blocks') }
                        onChange={ onChangeBannerButtons }
                        value={ bannerButtons }
                    />
                </div>
            </div>

        );
    },

    /**
     * The save function determines how the different attributes should be combined into the final markup.
     * Which is then serialised into the post_content.
     *
     * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
     *
     * @param {Object} props Props.
     * @returns {Mixed} JSX Frontend HTML.
     */
    save: (props) => {
        return (
            <div className={ props.className }>
                <div id="home-banner" style={{backgroundImage: `url(${ props.attributes.mediaURL })`}}>
                    <div class="container">
                        <div class="row">
                            <div class="col-12">
                                <div class="content-inner">
                                    <RichText.Content tagName="h1" className={ props.className } value={ props.attributes.title } />
                                    <RichText.Content tagName="p" className={ props.className } value={ props.attributes.content } />
                                    <RichText.Content tagName="ul" className="banner-buttons" value={ props.attributes.bannerButtons } />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );
    },
});

Редактировать 2 : Вот мой неудачный взгляд на это

// Importing code libraries for this block
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { RichText, MediaUpload, InspectorControls } from '@wordpress/block-editor';
import { Button, ColorPicker, ColorPalette, Panel, PanelBody, PanelRow } from '@wordpress/components';

/**
 * Register the Block
 * 
 * @link https://wordpress.org/gutenberg/handbook/block-api/
 * @param  {string}   name     name.
 * @param  {Object}   settings settings.
 * @return {?WPBlock}          The block, otherwise `undefined`.
 */
registerBlockType('ccm-block/banner-block', {
    title: __('Banner Block'),
    icon: 'format-image', // from Dashicons → https://developer.wordpress.org/resource/dashicons/.
    category: 'layout', // E.g. common, formatting, layout widgets, embed.
    keywords: [
        __('Banner Block'),
        __('CCM Blocks'),
    ],
    attributes: {
        mediaID: {
            type: 'number'
        },
        mediaURL: {
            type: 'string'
        },
        title: {
            type: 'array',
            source: 'children',
            selector: 'h1'
        },
        content: {
            type: 'array',
            source: 'children',
            selector: 'p'
        },
        bannerButtons: {
            type: 'array',
            source: 'children',
            selector: '.banner-buttons',
        },
        items: {
            source: 'query',
            default: [],
            selector: '.item',
            query: {
                title: {
                    type: 'string',
                    source: 'text',
                    selector: '.title'
                },
                index: {            
                    type: 'number',
                    source: 'attribute',
                    attribute: 'data-index'            
                }           
            }
        }
    },

    /**
     * The edit function relates to the structure of the block when viewed in the editor.
     *
     * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
     *
     * @param {Object} props Props.
     * @returns {Mixed} JSX Component.
     */
    edit: (props) => {

        const {
            attributes: { mediaID, mediaURL, title, content, bannerButtons, items },
            setAttributes, className
        } = props;

        const onSelectImage = (media) => {
            setAttributes({
                mediaURL: media.url,
                mediaID: media.id,
            });
        };

        const onChangeTitle = (value) => {
            setAttributes({ title: value });
        };

        const onChangeContent = (value) => {
            setAttributes({ content: value });
        };

        const onChangeBannerButtons = (value) => {
            setAttributes({ bannerButtons: value });
        };

        // Clone an array of objects
        function _cloneArray(arr) {
            if (Array.isArray(arr)) {
              for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
                arr2[i] = arr[i];
              }
              return arr2;
            } else {
              return Array.from(arr);
            }
        }
        // return repeater items
        var itemList = items.sort(function(a, b){
            return a.index - b.index;
        }).map(function(item){
            console.log(item);
            return(
                <RichText
                    tagName="h1"
                    placeholder={ __('Test', 'ccm-blocks') }
                    value={ item.title }
                    onChange={ function(value){
                        var newObject = Object.assign({}, item, {
                            title: value
                        });
                        setAttributes({
                            items: [].concat(_cloneArray(items.filter(function(itemFilter){
                                return itemFilter.index != item.index;
                            })), [newObject])
                        });
                    } }
                />
            );
        });

        // 
        console.log(itemList);

        return (
            <div className={className}>
                <div id="#home-banner">
                    <RichText
                        className="item-list"
                        tagName="h1"
                        value={ itemList }
                    />

                    <Button
                        className="button add-row"
                        onClick={ function(){
                            setAttributes({
                                items: [].concat(_cloneArray(items), [{
                                    index: items.length,
                                    title: ""
                                }])
                            });
                        } }
                    >
                        Add a button
                    </Button>

                    <MediaUpload
                        onSelect={onSelectImage}
                        allowedTypes="image"
                        value={mediaID}
                        render={({ open }) => (
                            <Button className={mediaID ? 'image-button' : 'button button-large'} onClick={open}>
                                {!mediaID ? __('Upload Image', 'ccm-blocks') : <img src={mediaURL} alt={__('Featured Image', 'ccm-blocks')} />}
                            </Button>
                        )}
                    />

                    <RichText
                        tagName="h1"
                        placeholder={__('Insert Title Here', 'ccm-blocks')}
                        className={className}
                        onChange={onChangeTitle}
                        value={title}
                    />

                    <RichText
                        tagName="p"
                        placeholder={__('Insert your short description here...', 'ccm-blocks')}
                        className={className}
                        onChange={onChangeContent}
                        value={content}
                    />

                    <RichText
                        tagName="ul"
                        multiline="li"
                        className="banner-buttons"
                        placeholder={ __('Add a banner button link (max of 2)', 'ccm-blocks') }
                        onChange={ onChangeBannerButtons }
                        value={ bannerButtons }
                    />
                </div>
            </div>

        );
    },

    /**
     * The save function determines how the different attributes should be combined into the final markup.
     * Which is then serialised into the post_content.
     *
     * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
     *
     * @param {Object} props Props.
     * @returns {Mixed} JSX Frontend HTML.
     */
    save: (props) => {
        return (
            <div className={ props.className }>
                <div id="home-banner" style={{backgroundImage: `url(${ props.attributes.mediaURL })`}}>
                    <div class="container">
                        <div class="row">
                            <div class="col-12">
                                <div class="content-inner">
                                    <RichText.Content tagName="h1" className={ props.className } value={ props.attributes.title } />
                                    <RichText.Content tagName="p" className={ props.className } value={ props.attributes.content } />
                                    <RichText.Content tagName="ul" className="banner-buttons" value={ props.attributes.bannerButtons } />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );
    },
});

1 Ответ

1 голос
/ 20 января 2020

Я понял это !! После бесчисленных часов возни с этим вот что я придумал. Это грубая версия того, что я хочу, но она определенно работает! Вот ссылка на один из найденных мной руководств ссылка .

// Importing code libraries for this block
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { RichText } from '@wordpress/block-editor';
import { Button } from '@wordpress/components';

// Register the block
registerBlockType( 'test-block/custom-repeater-block', {
    title: __('Repeater Block'),
    icon: 'layout',
    category: 'layout',
    keywords: [
        __('Custom Block'),
    ],
    attributes: {
        info: {
            type: 'array',
            selector: '.info-wrap'
        }
    },

    // edit function
    edit: (props) => {
        const {
            attributes: { info = [] },
            setAttributes, className
        } = props;

        const infoList = (value) => {
            return(
                value.sort((a, b) => a.index - b.index).map(infoItem => {
                    return(
                        <div className="info-item">
                            <Button
                                className="remove-item"
                                onClick={ () => {
                                    const newInfo = info.filter(item => item.index != infoItem.index).map(i => {
                                        if(i.index > infoItem.index){
                                            i.index -= 1;
                                        }
                                        return i;
                                    } );
                                    setAttributes({ info: newInfo });
                                } }
                            >&times;</Button>
                            <h3>Number {infoItem.index}</h3>
                            <RichText
                                tagName="h4"
                                className="info-item-title"
                                placeholder="Enter the title here"
                                value={infoItem.title}
                                style={{ height: 58 }}
                                onChange={ title => {
                                    const newObject = Object.assign({}, infoItem, {
                                        title: title
                                    });
                                    setAttributes({
                                        info: [...info.filter(
                                            item => item.index != infoItem.index
                                        ), newObject]
                                    });
                                } }
                            />
                            <RichText
                                tagName="p"
                                className="info-item-description"
                                placeholder="Enter description"
                                value={infoItem.description}
                                style={{ height: 58 }}
                                onChange={ description => {
                                    const newObject = Object.assign({}, infoItem, {
                                        description: description
                                    });
                                    setAttributes({
                                        info: [...info.filter(
                                            item => item.index != infoItem.index
                                        ), newObject]
                                    });
                                } }
                            />
                        </div>
                    )
                })
            )
        }

        return(
            <div className={className}>
                <div className="info-wrap">{infoList(info)}</div>
                <Button onClick={title => {
                    setAttributes({
                        info: [...info, {
                            index: info.length,
                            title: "",
                            description: ""
                        }]
                    });
                }}>Add Item</Button>
            </div>
        );
    },

    // save function
    save: (props) => {
        const info = props.attributes.info;
        const displayInfoList = (value) => {
            return(
                value.map( infoItem => {
                    return(
                        <div className="info-item">
                            <RichText.Content
                                tagName="h4"
                                className="info-item-title"
                                value={infoItem.title}
                                style={{ height: 58 }}
                            />
                        </div>
                    )
                } )
            )
        }

        return(
            <div className={props.className}>
                <div className="info-wrap">{ displayInfoList(info) }</div>
            </div>
        );
    }
} )
...