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/
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).