Search code examples
phpreactjswordpresspluginswordpress-gutenberg

Plugin's admin dashboard components not showing up after registering Gutenberg block


I am trying to create a basic plugin that will create both admin dashboard as well as a Gutenberg block. I first started with creating the admin side and it was working perfectly fine as I followed Wordpress's tutorial [here][1]. But then when I registered a block, the admin page is showing up but no React component which only include an input field.

This is my folder structure with only admin side (no block):

my-plugin
  -- build
  -- src
    -- admin
       adminIndex.js
      -- stylesheet
         style.css
      -- components
        -- SomeComponent.js
    index.js
  plugin.php
  package.json

adminIndex.js file looks like this:

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

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

And this is what plugin.php file looks like without block:

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

    public function menu_item() {
        add_menu_page(
            'My Plugin',
            'My Plugin',
            'manage_options',
            'my-plugin',
            ' 
               <h2>Pages</h2>
               <div id="my-plugin"></div>
            ',
            'dashicons-schedule',
            3
        );
    }

    public function load_admin_scripts( $hook ) {
        // Load only on ?page=my-plugin
        if ( 'toplevel_page_my-plugin' !== $hook ) {
            return;
        }

        // 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' );
    }
}

Up until this point the app works and the admin page and the react component is showing up. After this I tried adding a block and this is how the folder structure looks like:

my-plugin
  -- build
  -- src
    -- admin
       adminIndex.js
      -- stylesheet
         style.css
      -- components
        -- SomeComponent.js
    -- blocks
       -- block-1
          block.json
          edit.js
          blockIndex.js
          save.js
          editor.scss
          style.scss
    index.js
  plugin.php
  package.json

index.js file is the import of both of those admin and block index files:

import './admin/adminIndex.js
import './blocks/block-1/blockIndex.js';

And in plugin.php file I registered the block with this:

add_action( 'init', [ $this, 'register_blocks' ] );

public function register_blocks() {
     register_block_type( __DIR__ . '/build/blocks/block-1' );
}

What am I doing wrong here? Is there something wrong with enqueuing scripts above? Admin page worked perfectly fine until i registered a block. Seems like the build is giving the block more priority. Someone please help.

UPDATED

This is how the build folder looks like:

build blocks block-1 block.json index.asset.php index.css index.css.map index.js index.js.map style-index.css style-index.css.map


  [1]: https://developer.wordpress.org/block-editor/how-to-guides/data-basics/

Solution

  • It seems like both your admin and block scripts are being built into the same index.js file in the build directory. This could be causing conflicts. You could try configuring your build process to output separate files for the admin and block scripts.

    In your register_blocks function, you could try enqueuing the block script separately using wp_enqueue_script. This would ensure that the block script is only loaded when needed, and not on the admin page. Here's an example:

    public function register_blocks() {
        // Register the block script
        wp_register_script(
            'my-block',
            plugins_url( 'build/block.js', __FILE__ ),
            array( 'wp-blocks', 'wp-element', 'wp-editor' ),
            filemtime( plugin_dir_path( __FILE__ ) . 'build/block.js' )
        );
    
        // Register the block
        register_block_type( 'my-plugin/block-1', array(
            'editor_script' => 'my-block',
        ) );
    }
    

    Make sure that the path you're providing to register_block_type is correct. If the path is incorrect, the function could be failing silently, causing the block script not to be enqueued. In the example above, I've used a string slug ('my-plugin/block-1') instead of a path for the block name. This is the recommended way to register blocks according to the https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/ Handbook.

    Hi, thanks for your response. Do I keep load_admin_scripts's wp_register_script path build/index.js as it is? What should I point it to? Reply:

    If you have separated your build files into admin.js and block.js as suggested, you should update the wp_register_script in load_admin_scripts to point to the admin.js file. Here's how you can do it:

    public function load_admin_scripts( $hook ) {
         if ( 'toplevel_page_my-plugin' !== $hook ) {
            return;
         }
         $asset_file = include plugin_dir_path( __FILE__ ) . 'build/admin.asset.php';
         foreach ( $asset_file['dependencies'] as $style ) {
             wp_enqueue_style( $style );
         }
         wp_register_script(
             'my-plugin',
             plugins_url( 'build/admin.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' );
    }
    

    I've changed build/index.js to build/admin.js in the plugins_url function. This assumes that your build process outputs admin.js in the build directory. You'll need to adjust this to match your actual build process and directory structure.

    Remember to also update the path in the include function to match the new asset file for your admin script (admin.asset.php).