在古腾堡编辑器中获取“块“我的插件/块名称”已注册”

s.k*_*han 5 php wordpress wordpress-theming reactjs wordpress-gutenberg

我正在尝试创建一个具有多个块和一个管理页面的插件。一切似乎都运转良好。管理页面正在显示,块也正在工作。但是当我进入古腾堡编辑器时,控制台中出现错误,这让我担心我所做的是否错误。

这是错误:

'Block "my-plugin/block-1" is already registered' 'Block "my-plugin/block-2" is already registered'

这是插件 php 文件:

class MY_PLUGIN{
    public function __construct() {
        add_action( 'admin_menu', [ $this, 'menu_item' ] );
        add_action( 'admin_enqueue_scripts', [ $this, 'load_custom_wp_admin_scripts' ] );
        add_action( 'init', [ $this, 'register_blocks' ] );
    }

    /**
    * Initialize the plugin
    */
    public static function init(){
        static $instance = false; 
        if( !$instance ) {
            $instance = new self();
        }
        return $instance;
    }

    /**
    * Create a new admin page for our app.
    */
    public function menu_item() {
        add_menu_page(
            'My Plugin',
            'My Plugin',
            'manage_options',
            'my-plugin',
            [ $this, 'dashboard_page' ],
            'dashicons-schedule',
            3
        );
    }

    /**
    * Admin page markup.
    */
    public function dashboard_page() {
        echo '
            <h2>Pages</h2>
            <div id="my-plugin"></div>
        ';
    }

    /**
    * Load admin scripts and stylesheets
    */
    public function load_custom_wp_admin_scripts( $hook ) {
        // Load only on ?page=my-plugin
        if ( 'toplevel_page_my-plugin' !== $hook ) {
            return;
        }

        // Load the required WordPress packages.

        // Automatically load imported dependencies and assets version.
        $asset_file = include plugin_dir_path( __FILE__ ) . 'build/index.asset.php';

        // Enqueue CSS dependencies.
        foreach ( $asset_file['dependencies'] as $style ) {
            wp_enqueue_style( $style );
        }

        // Load our app.js.
        wp_register_script(
            'my-plugin',
            plugins_url( 'build/index.js', __FILE__ ),
            $asset_file['dependencies'],
            $asset_file['version']
        );
        wp_enqueue_script( 'my-plugin' );

        // Load our style.css.
        wp_register_style(
            'my-plugin',
            plugins_url( 'src/admin/stylesheet/style.css', __FILE__ ),
            array(),
            $asset_file['version']
        );
        wp_enqueue_style( 'my-plugin' );
    }

    public function register_blocks() {
        register_block_type( __DIR__ . '/build/blocks/block-1' );
        register_block_type( __DIR__ . '/build/blocks/block-2' );
   }
}
Run Code Online (Sandbox Code Playgroud)

每个块的index.js 文件如下所示:

import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import './editor.scss';
import Edit from './edit';
import Save from './save';
import metadata from './block.json';

/**
 * Every block starts by registering a new block type definition.
*/
registerBlockType( metadata, {
    edit: Edit,
    save: Save,
} );
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么吗?

更新* 这是 block.json 的样子。两个块相同,只是名称和标题不同。就像块 1 和块 2 一样:

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 2,
    "name": "my-plugin/block-1",
    "version": "0.1.0",
    "title": "Block 1",
    "category": "text",
    "icon": "flag",
    "description": "Some description",
    "attributes": {
        "message": {
            "type": "string",
            "source": "text",
            "selector": "div"
        }
    },
    "supports": {
        "html": false
    },
    "textdomain": "block-1",
    "editorScript": "file:../../index.js",
    "editorStyle": "file:../../index.css",
    "style": "file:../../style-index.css"
}

Run Code Online (Sandbox Code Playgroud)

文件夹结构:

在此输入图像描述

管理索引.js:

import { render }                   from '@wordpress/element';
import App                          from './components/App/App';

window.addEventListener(
    'load',
    function () {
        render(
            <App />,
            document.querySelector( '#my-plugin' )
        );
    },
    false
);
Run Code Online (Sandbox Code Playgroud)

更新:

按照 S.Walsh 的建议添加自定义 webpack 文件后,在管理端出现这些错误并且块丢失。

在此输入图像描述

更新:

实施 S.Walsh 的建议后,这些块工作正常,但管理页面未显示任何组件。所以我更新了load_custom_wp_admin_scripts函数来构建注册脚本的路径:

public function load_custom_wp_admin_scripts($hook) {
    if ('toplevel_page_my-plugin' !== $hook) {
        return;
    }

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

    foreach ( $asset_file['dependencies'] as $style ) {
        wp_enqueue_style( $style );
    }

    wp_register_script('my-plugin', plugins_url('build/admin/index.js', __FILE__), $asset_file['dependencies'], $asset_file['version']);
    wp_enqueue_script('my-plugin');

    wp_register_style('my-plugin', plugins_url('src/admin/stylesheet/style.css', __FILE__), array(), $asset_file['version']);
    wp_enqueue_style('my-plugin');
}
Run Code Online (Sandbox Code Playgroud)

组件现在已显示,但样式表没有任何效果。

更新:

为了使管理样式生效,css 文件应更改为 scss。并且在load_custom_wp_admin_scripts功能上也进行了更新。我还删除了 view.js 文件,因为不需要它。

S.W*_*lsh 3

该错误是由以下函数在plugin.phpload_custom_wp_admin_scripts()中触发的:

  1. 该文件包含src/index.js用于load_custom_wp_admin_scripts().

  2. 这些块也通过使用init挂钩上的register_blocks()每个块的函数进行注册。block.json

当您访问自定义管理页面时,admin_enqueue_scriptsinit挂钩都会尝试注册块,从而产生错误。

您的屏幕截图显示脚本入口点正在将所有资产编译到index.asset.php因此您的块构建目录仅包含block.json文件而不包含其资产。

最佳实践是保持块代码独立于任何其他插件 JavaScript,对于这种项目设置,您可以定义多个入口点来构建所需的资产。

解决方案

让我们从一开始就建立一个具有多个块的基本插件项目,以探索替代方法:

1. 通过命令行使用@wordpress/create-block进行项目设置:

# 1. Create "my-plugin" and install required files
npx @wordpress/create-block@latest my-plugin

# 2. Remove the default src directory that contains the default single block
rmdir /s my-plugin\src

# 3. Make a new src\blocks directory and enter it
mkdir my-plugin\src\blocks && cd my-plugin\src\blocks

# 4. Use create block to scaffold new blocks as required with --no-plugin option
npx @wordpress/create-block@latest --no-plugin block-1
npx @wordpress/create-block@latest --no-plugin block-2

# 5. Run build
cd [path-to]\my-plugin
npm run build 
Run Code Online (Sandbox Code Playgroud)

更新create_block_my_plugin_block_init()函数以注册两个块:

我的插件.php

function create_block_my_plugin_block_init() {
    register_block_type( __DIR__ . '/build/blocks/block-1' );
    register_block_type( __DIR__ . '/build/blocks/block-2' );
}
add_action( 'init', 'create_block_my_plugin_block_init' );
Run Code Online (Sandbox Code Playgroud)

从编辑器测试插件以查看两者block-1block-2加载而不会出现错误。

在此阶段,您已经为具有两个工作块的基本插件奠定了坚实的基础,并使用其资产进行了正确编译。

接下来的步骤是可选的,可以使用管理页面扩展插件。

2. 管理页面设置

src/admin/目录将包含一个index.js脚本,该脚本stylesheet/style.scss根据构建过程的需要导入 . 不index.js 加载任何块。

src/admin/index.js

import './stylesheet/style.scss';
...
// Other code for Admin Page..
Run Code Online (Sandbox Code Playgroud)

3. 构建设置

创建一个新的自定义webpack.config.js,为您的项目启用额外的入口点来构建所有必需的资产:

[我的插件]/webpack.config.js

const defaultConfig = require('@wordpress/scripts/config/webpack.config');

module.exports = {
    ...defaultConfig,
    entry: {
        'admin/index': './src/admin/',
        'blocks/block-1/index': './src/blocks/block-1/',
        'blocks/block-2/index': './src/blocks/block-2/'
    },
};
Run Code Online (Sandbox Code Playgroud)

4. 更新主插件文件 接下来,更新my-plugin.php以包含您的原始class MY_PLUGIN代码,并进行以下更新load_custom_wp_admin_scripts()

我的插件.php

class MY_PLUGIN
{
...

    /**
     * Load admin scripts and stylesheets
     */
    public function load_custom_wp_admin_scripts($hook)
    {
        // Load only on ?page=my-plugin
        if ('toplevel_page_my-plugin' !== $hook) {
            return;
        }

        // Register and load admin script with dependancies
        $asset_file = include plugin_dir_path(__FILE__) . 'build/admin/index.asset.php';
        wp_register_script('my-plugin-admin', plugins_url('build/admin/index.js', __FILE__), $asset_file['dependencies'], $asset_file['version']);
        wp_enqueue_script('my-plugin-admin');

        // Register and load admin style.css.
        $admin_style = plugins_url('build/admin/style-index.css', __FILE__);
        wp_register_style('my-plugin-admin-style', $admin_style, array(), '1.0'); // check
        wp_enqueue_style('my-plugin-admin-style');
    }
...
}
Run Code Online (Sandbox Code Playgroud)

检查所有文件路径是否正确,然后重建项目。每个块的构建目录现在仅包含该块资产;管理页面中的脚本和样式资源输出到build\admin\.

项目目录设置示例

现在您可以继续创建任意数量的新块!

其他注释 更新的问题屏幕截图中显示的错误表明:

  1. 缺少“view.asset.php”意味着“view.js”已定义为 block.json,但块目录中不存在“view.js”或者是不同的文件名。
  2. 与上述相同适用于“editorSrc”,其中“index.js”丢失或文件名/路径不匹配。

这两个问题都可以通过添加缺少的文件或更新其声明以block.json正确的项目路径/文件名来解决,例如:

    "editorScript": "file:./index.js",
    "viewScript": "file:./view.js"
Run Code Online (Sandbox Code Playgroud)

确保在再次测试之前重建项目并清除浏览器缓存。