Search code examples
phpwordpresswordpress-gutenberggutenberg-blocks

Gutenberg Blocks: registering more than one block with `register_block_type_from_metadata()` throws errors in the console


I'm practicing how to create Gutenberg blocks plugin. I use @wordpress/create-block to create a blocks plugin.

Edit: I didn't use the wp-cli scaffold as I initially stated, what I meant to write is that I used @wordpress/create-block.

The scaffold is made to only have one block on it, so, if you want more than one block you have to modify the structure, which is not that hard, but, I want the blocks to use block.json to register blocks with register_block_type_from_metadata(), which I achieved, but the problem is that if I use this code (register_block_type_from_metadata twice) in the main plugin's PHP file:

function blocks_boilerplate_block_init() {
    register_block_type_from_metadata( __DIR__ . '/src/blocks/example');
    register_block_type_from_metadata( __DIR__ . '/src/blocks/example2');
}
add_action( 'init', 'blocks_boilerplate_block_init' );

To register the blocks, the blocks get registered and they work without problems, but the Chrome console shows two errors.

Block "create-block/boilerplate-example" is already registered.

Block "create-block/guten-block-example2" is already registered.

If I use register_block_type_from_metadata() only once, the error goes away.

Any ideas on how to make the errors disappear?


Solution

  • The problem was, when you use @wordpress/create-block to create a plugin with a block in it, and then you use npm start to run everything, webpack compiles all the blocks JavaScript code into a single file, which is fine and actually is desired, that way you don't have to enqueue a bunch of files. The block.json file includes a line "editorScript": "file:../build/index.js" (or something similar) to enqueue the main compiled JS file, and if you have only one block, that line is ok in the block.json file, but when you modify the structure of the plugin to include more blocks and every block has its own block.json file, including the editorScript line, then the blocks are registered several times, one for every block.json file you have, so, as a temporary solution, I deleted the editorScript line from all block.json files except one, and the errors disappeared, I didn't like that solution because it breaks consistency, so, I placed the following code in the plugin main php file:

    function qas_enqueue_blocks_scripts() {
        $asset_file = require plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
        wp_enqueue_script( 'qas-main', plugins_url( '/build/index.js', __FILE__ ), $asset_file['dependencies'], 1.0, false);
    }
    add_action( 'enqueue_block_editor_assets', 'qas_enqueue_blocks_scripts');
    

    The code above enqueues the main index.js file to the block editor and gets the file dependencies from /build/index.asset.php which is automatically generated when you run the initial commands to create the plugin and initial block. Using that code, you don't need to use the editorScript line anywhere, so you can delete it from all block.json files.

    Other way to solve this is to modify the webpack configuration to compile only the code for the specific block to the main JS file, and then keep using editorScript in every block.json, but I haven't tried that yet.