admin管理员组

文章数量:1287548

I am trying to create UI in gutenberg block editor where main Editor interface picks persons from the database of personnel (separate custom table in MySQL), and each person has button beneath, which when pressed opens a 'window' where short biography could be entered.

Data about which persons are picked are saved in regular page, but biography for each person should be saved in custom post type 'biographies', so it can be shown on more than one page, as popup and also as separate page.

I decided that best approach would be to embed another instance of block-editor, similar to reusable blocks. However, I can not get it to save content and to show proper blocks in inserter (it shows blocks from context of main editor)

This is what I came with so far (code is component which opens editor instance popup on a button and closes it with another button in popup:

 /**
 * Component for entering biography
 */

import { BlockEditorProvider, BlockList, WritingFlow, ObserveTyping } from '@wordpress/block-editor';
import { Button } from '@wordpress/components';
import { useState, useEffect, useSelect } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { EntityProvider, useEntityBlockEditor, useEntityId  } from '@wordpress/core-data';

// const TABLE = 'tla_mit_lecturers_biography';


const BiographyModal = ({ name, showButton, postID, setPostID }) => {
    const [ isOpen, setIsOpen ] = useState(false);
    const [ blocks, onInput, onChange ] = useEntityBlockEditor(
        'postType',
        'biographies',
        { id: postID }
    );
    const retrievedID = useEntityId( 'postType', 'biographies' );
    useEffect(() => setPostID(retrievedID), [retrievedID])
    const editorSettings = {
        allowedBlockTypes: ['core/paragraph']
    }

    const editorInstance =
            // <EntityProvider
            //  kind="postType"
            //  type="biographies"
            //  id={postID}
            // >
                <BlockEditorProvider
                    value={ blocks }
                    onChange={ onChange }
                    onInput={ onInput }
                    // selection={ selection }
                    settings={ editorSettings }
                    useSubRegistry={ true }
                >
                    <WritingFlow>
                        <ObserveTyping>
                            <BlockList />
                        </ObserveTyping>
                    </WritingFlow>
                </BlockEditorProvider>;
            // </EntityProvider>;

    const modal =
        <div className="biography-modal">
            <h3>{ `Životopis ${ name }` }</h3>
            {editorInstance}
            <Button isDefault onClick={ () => setIsOpen(false) }>
                Završi
            </Button>
        </div>;


    return (
        <div className="biography-module">
            {
                (showButton || isOpen) &&
                <Button isDefault disabled={isOpen} onClick={ () => setIsOpen( true ) }>Uredi životopis</Button>
            }
            { isOpen && modal }
        </div>
    )
}

export default BiographyModal;

I am also not sure if block editor should be wrapped in EntityProvider or not, it seems to do nothing. Although editor appears and typing inside is possible, it gives error Uncaught (in promise) TypeError: can't access property "blocks", record is undefined. I guess it could be because BlockEditorProvider and useEntityBlockEditor operate on different registries.

本文标签: Embedded block editor in block editor