When WordPress 5.8 was released I discovered that some of my block based plugins caused messages in the new block based widget editor.
User Notice: wp_enqueue_script() was called incorrectly. “wp-editor” script should not be enqueued together with the new widgets editor (wp-edit-widgets or wp-customize-widgets). Please see Debugging in WordPress for more information. (This message was added in version 5.8.0.)
I decided that I needed to update my block based plugins so that they were built using the latest version of the block API. Some of the plugins needed migrating from a hand cranked webpack build. Others just needed the changes for apiVersion:2
.
In this post:
- Problems with the new Widget block editor in WordPress 5.8
- Steps to migrate to wp-scripts
- Summary of plugins and GitHub issues
- References
Problems with the new Widget block editor in WordPress 5.8
In a number of plugins I have wp-editor
listed as a dependency on the wp_register_script()
for the blocks. This is the old style of registering blocks. The new Widgets block editor doesn’t care for this and issues a _doing_it_wrong
Notice.
The blocks required wp-editor
in order to use Server Side Rendering. For webpack build they accessed ServerSideRender
using
const { ServerSideRender } = wp.editor;
For wp-scripts using version 1 of the API they were using
import { ServerSideRender } from '@wordpress/editor';
If Server Side Rendering is needed then the code needs to be changed as below, otherwise the import, and therefore the dependency, can be removed.
import ServerSideRender from '@wordpress/server-side-render';
In order to implement this change the blocks that are built using webpack
need to be converted to use wp-scripts
and to use apiVersion:2
for block registration.
Steps to migrate to wp-scripts
- Change the JavaScript from
const
toimport
- Remove unnecessary files
- Change
package.json
- Change / create
block.json
for each block - Change each block’s Server Side Registration to register the block from
block.json
- Change each block’s
index.js
to register the block - Change each block’s outer wrapper
- Update
node_modules
and rebuild - Internationalize and localize
Change the JavaScript from const
to import
Change the references to functions
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { ServerSideRender } = wp.editor;
import {__} from "@wordpress/i18n";
import { registerBlockType } from '@wordpress/blocks';
import ServerSideRender from '@wordpress/server-side-render';
Add other imports for apiVersion 2
import { useBlockProps } from '@wordpress/block-editor';
Remove unnecessary files
Delete the files used by the original webpack build that aren’t needed by wp-scripts.
webpack.config.js
.babelrc
Change package.json
Update package.json
to implement the wp-scripts
commands. The standard scripts
are:
"scripts": {
"build": "wp-scripts build",
"format": "wp-scripts format",
"lint:css": "wp-scripts lint-style",
"lint:js": "wp-scripts lint-js",
"start": "wp-scripts start",
"packages-update": "wp-scripts packages-update"
"dev": "wp-scripts start"
},
Note: dev
is an alias of start
.
Additionally, for internationalization, translation and localization, I add the following commands. Here they’re customized for the sb-starting-block
plugin.
"makepot": "wp i18n make-pot . languages/sb-starting-block.pot --exclude=node_modules,vendor,src/*.js",
"makejson": "wp i18n make-json languages --no-purge",
"l10n": "l10n sb-starting-block"
dependencies
and devDependencies
will also need updating. These are the latest entries in the package.json
file created by npx @wordpress/create-block
.
"dependencies": {
"@wordpress/block-editor": "^7.0.2",
"@wordpress/blocks": "^11.1.0",
"@wordpress/i18n": "^4.2.2"
},
"devDependencies": {
"@wordpress/scripts": "^18.0.1"
}
To update an existing plugin to the latest versions run the packages-update
command.
npm run packages-update
Change / create block.json
for each block
For a multi-block plugin put the block.json
file for each block in its own folder within the src
folder. For a single block plugin the file can be in the plugin’s root directory.
For example the file src/starting-block/block.json
might be:
{
"apiVersion": 2,
"name": "oik-sb/sb-starting-block",
"title": "Starting block",
"category": "widgets",
"icon": "megaphone",
"description": "Starting block - Server Side Rendered",
"supports": { },
"textdomain": "sb-starting-block",
"editorScript": "file:../../build/index.js",
"editorStyle": "file:../../build/index.css",
"style": "file:../../build/style-index.css"
}
Notes:
apiVersion
set to 2.supports
may contain many attributes. See below.editorScript
,editorStyle
andstyle
indicate the directory for the build files.
"supports": {
"align": true,
"html": false,
"customClassName": true,
"className": true,
"color": {
"gradients": true,
"text": true,
"background": true
},
"typography": {
"fontSize": true,
"lineHeight": true
},
"padding": true
},
The supports
structure provides many configurable settings. If you include color
and typography
then, for Server Side Rendered blocks, additional fields need to be defined in attributes
where the setting is true
.
Note: The block’s supports
attributes can be overriden by the theme’s theme.json
file.
Change each block’s Server Side Registration to register the block from block.json
Register the block using the metadata loaded from the block.json
file. For a dynamic block the callback function is passed in the $args
array.
function oik_sb_sb_starting_block_block_init() {
$args = [ 'render_callback' => 'oik_sb_sb_starting_block_dynamic_block'];
register_block_type_from_metadata( __DIR__ . '/src/starting-block', $args );
}
add_action( 'init', 'oik_sb_sb_starting_block_block_init' );
Change each block’s index.js
to register the block
Change the block registration to use the definition from the server registration. The settings
parameter doesn’t include values that are now defined in block.json
.
registerBlockType( 'oik-sb/sb-starting-block', {
edit: Edit,
save
} );
Change each block’s outer wrapper
In the JavaScript code change the Edit function to use useBlockProps()
. This function will set class names for the supports
settings defined in block.json
.
export default function Edit ( { attributes, className, isSelected, setAttributes } ) {
const { textAlign } = attributes;
const blockProps = useBlockProps( {
className: classnames( {
[ `has-text-align-${ textAlign }` ]: textAlign,
} ),
} );
return (
<div { ...blockProps}>
<ServerSideRender block="oik-sb/sb-starting-block" attributes={attributes}
/>
</div>
);
}
In this example the value of the textAlign
control is also being taken into account.
For Server Side rendered code the equivalent logic is implemented using get_block_wrapper_attributes()
.
function oik_sb_sb_starting_block_dynamic_block( $attributes ) {
$classes = '';
if ( isset( $attributes['textAlign'] ) ) {
$classes .= 'has-text-align-' . $attributes['textAlign'];
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
$content = __( 'Starting block.', 'sb-starting-block');
$html = sprintf( '<div %1$s>%2$s</div>', $wrapper_attributes, $content );
return $html;
}
For some blocks it may also be necessary to apply this wrapper during save
. In this case you need to use useBlockProps.save()
.
save: props => {
const blockProps = useBlockProps.save();
return(
<div {...blockProps} >
<Dashicon icon={props.attributes.dashicon} />
</div>
);
}
Update node_modules
and rebuild
The node_modules used in the webpack build need to be replaced by the modules needed by wp-scripts. To get a working version of wp-scripts use the following steps.
- Change to the plugin’s root directory.
- Remove the existing
node_modules
folder npm install
npm install @wordpress/scripts --save-dev
Once installed the blocks can be rebuilt
npm run dev
– for the development buildnpm run build
– for a production release
Internationalize and localize
When the blocks have been rebuilt and tested in the widget block editor then the internationalization ( i18n ), translation and localization ( l10n ) can be implemented. See Internationalizing and localizing block based plugins.
Summary of plugins and GitHub issues
If you want to read more about my implementation then you’ll find it’s fairly well annotated in my GitHub issues. Some of these plugins are multi-block plugins, others are single block. All of them are available from oik-plugins.com, several are on wordpress.org.
Plugins | Original build | GitHub issue(s) |
---|---|---|
oik | webpack | bobbingwide/oik#177 |
oik-blocks | webpack | bobbingwide/oik-blocks#47 |
oik-bob-bing-wide | webpack | bobbingwide/oik-bob-bing-wide#42 |
oik-css | webpack | bobbingwide/oik-css#16 |
oik-magnetic-poetry | webpack | bobbingwide/oik-magnetic-poetry#4 |
oik-squeeze | wp-scripts | bobbingwide/oik-squeeze#13 |
sb-breadcrumbs-block | wp-scripts | bobbingwide/sb-breadcrumbs-block#7 |
sb-chart-block | wp-scripts | bobbingwide/sb-chart-block#13 |
sb-children-block | wp-scripts | bobbingwide/sb-children-block#5 |
sb-coming-up | wp-scripts | bobbingwide/sb-coming-up#2 |
sb-field-block | wp-scripts | |
sb-post-edit-block | wp-scripts | bobbingwide/sb-post-edit-block#5 |
sb-prevnext-block | wp-scripts | |
sb-starting-block | wp-scripts | bobbingwide/sb-starting-block#2 |
sb-toolicons-block | wp-scripts | |
uk-tides | webpack | bobbingwide/uk-tides#9 |