使用内部块的自定义WP块使编辑器崩溃,不保存内容

时间:2021-06-03 作者:Tony Djukic

我终于开始着手为一个项目构建一个定制的Gutenberg/WP块,这基本上让我很不舒服。使用React、Node、WebPack、Gulp对我来说都是全新的,所以我必须处理一个学习曲线,但WP不完整和不准确的文档让事情变得更糟(他们的文档仍然说要使用wp.editor 但通过阅读GitHub中的门票,我了解到这是不受欢迎的,应该改为wp.blockEditor, 例如。)

现在,我的编辑器中有一个自定义块加载,应该可以接受InnerBlocks. 添加块并向其中添加块的过程很好。

出现问题的地方是页面/帖子“更新”之后。我犯了一堆不同的错误,还有一个白色的死亡屏幕。有时会出现的错误之一是React缩小#321错误。但也有其他错误,但并不总是相同的错误。

以下是用于注册我的块的代码:

const { __, setLocaleData } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { InnerBlocks } = wp.blockEditor; //was wp.editor

const blockStyle = {
    backgroundColor: \'#777\',
    color: \'#FFF\',
    padding: \'24px 2.5% 24px 2.5%\',
};

registerBlockType( \'custom-layout-blocks/custom-stripe-rows\', {
    title: __( \'Striped Block Row\', \'custom-layout-blocks\' ),
    icon: \'tide\',
    category: \'layout\',
    styles: [
        {
            name: \'magenta-stripes\',
            label: \'Magenta\',
            isDefault: true
        },
        {
            name: \'teal-stripes\',
            label: \'Teal\'
        },
        {
            name: \'evergreen-stripes\',
            label: \'Evergreen\'
        },
    ],
    edit() {
        return (
            <div style={blockStyle}><InnerBlocks /></div>
        );
    },
    save() {
        return (
            <div style={blockStyle}><InnerBlocks /></div>
        );
    }
} );
下面是相关的PHP:

defined( \'ABSPATH\' ) || exit;
    function custom_layoutblocks_load_textdomain() {
        load_plugin_textdomain( \'custom-layout-blocks\', false, basename( __DIR__ ) . \'/languages\' );
    }
    add_action( \'init\', \'custom_layoutblocks_load_textdomain\' );

    function custom_layoutblocks_register_block() {
        if( !function_exists( \'register_block_type\' ) ) {
            // Gutenberg is not active.
            return;
        }
        wp_register_script(
            \'custom-striped-rows\',
            plugins_url( \'build/index.js\', __FILE__ ),
            array( \'wp-blocks\', \'wp-i18n\', \'wp-element\', \'wp-block-editor\' ),
            filemtime( plugin_dir_path( __FILE__ ) . \'build/index.js\' )
        );
        wp_register_style(
            \'custom-editor\',
            plugins_url( \'css/custom-editor.css\', __FILE__ ),
            array( \'wp-edit-blocks\' ),
            filemtime( plugin_dir_path( __FILE__ ) . \'css/custom-editor.css\' )
        );
        wp_register_style(
            \'custom-style\',
            plugins_url( \'css/custom-front.css\', __FILE__ ),
            array(),
            filemtime( plugin_dir_path( __FILE__ ) . \'css/custom-front.css\' )
        );
        wp_style_add_data( \'custom-style\', \'path\', dirname( __FILE__ ) . \'/css/custom-front.css\' );
        register_block_type( \'custom-layout-blocks/custom-stripe-rows\', array(
            \'api_version\'   => 2,
            \'style\'         => \'custom-style\',
            \'editor_style\'  => \'custom-editor\',
            \'editor_script\' => \'custom-striped-rows\',
        ) );
        if( function_exists( \'wp_set_script_translations\' ) ) {
            wp_set_script_translations( \'custom-striped-rows\', \'custom-layout-blocks\' );
        }
    }
    add_action( \'init\', \'custom_layoutblocks_register_block\' );
**我已将所有前缀更改为“custom”,以保持此通用性,并适用于遇到此问题的任何其他人。

WebPack正在跟踪更改,文件也正在更新,我可以在我的开发环境和临时站点上运行插件。当我用其中的自定义块更新条目时,一切都会土崩瓦解。从那以后,一切似乎都乱成一团,内容没有出现在前端,甚至没有出现在源代码中。

Update:

下面是我在添加块和段落块后在编辑屏幕上看到的错误。

TypeError: null is not an object (evaluating \'(e.target.getAttribute("data-block")?e.target:e.target.closest("[data-block]")).getAttribute\')

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

Explanation of the issues in your code:

  1. The main one which causes the block editor to crash, is because you used InnerBlocks in the save function. You should instead use InnerBlocks.Content.

    See this and this for more details on InnerBlocks usage, accepted props, etc.

  2. As for the getAttribute error, it\'s because you did not use useBlockProps in the edit function (which should also be used in the save function).

    And why should you use useBlockProps, is because when you registered the block type in JavaScript (using registerBlockType()), you didn\'t set the apiVersion property, hence Gutenberg uses the api_version value (which is 2) you set via PHP (using register_block_type()), and when using the block API version 2, useBlockProps should be used, so that the block is properly wrapped, centered and "clickable".

So to fix the issues:

  • At the top in your script, replace the const { InnerBlocks } = wp.blockEditor; with:

    const { InnerBlocks, useBlockProps } = wp.blockEditor;
    
  • Use useBlockProps() in the edit function, and useBlockProps.save() and InnerBlocks.Content in the save function:

    edit() {
        const blockProps = useBlockProps( { style: blockStyle } );
    
        return (
            <div { ...blockProps }><InnerBlocks /></div>
        );
    },
    save() {
        const blockProps = useBlockProps.save( { style: blockStyle } );
    
        return (
            <div { ...blockProps }><InnerBlocks.Content /></div>
        );
    }
    

Additional Notes

  • Are you already using the @wordpress/scripts package to build your scripts (see JavaScript build setup in the block editor handbook)?

    Because if you are, you wouldn\'t need to manually specify the dependencies for your script, which is array( \'wp-blocks\', \'wp-i18n\', \'wp-element\', \'wp-block-editor\' ) in the question.

    However, you will need to use the import statement and not const when loading the dependencies in your script. So for example:

    // Instead of using "const":
    const { InnerBlocks, useBlockProps } = wp.blockEditor;
    
    // Use "import":
    import { InnerBlocks, useBlockProps } from \'@wordpress/block-editor\';
    

In response to your comment...

if I replace array( \'wp-blocks\', \'wp-i18n\', \'wp-element\', \'wp-block-editor\' ) with just array() or any other combination, excluding any of them or all of them, I still get an error

The following excerpt might help:

Here is how to use this asset file to automatically set the dependency list for enqueuing the script. This prevents having to manually update the dependencies, it will be created based on the package imports used within your block.

$asset_file = include( plugin_dir_path( __FILE__ ) . \'build/index.asset.php\');

wp_register_script(
  \'myguten-block\',
  plugins_url( \'build/index.js\', __FILE__ ),
  $asset_file[\'dependencies\'],
  $asset_file[\'version\']
);

相关推荐