Requirement. Every header (core/heading
) block needs to have a toggle control for adding or removing a custom class name to/from the resulting element.
Usage example. Building an automatic table of contents generator, which will pick only the headers having the custom class name. The admin needs to easily select headers that should be used for the table of contents.
(Related: here's how to define a custom static Block element acting as a placeholder where the table of contents, generated with Javascript, will be inserted: https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/writing-your-first-block-type/.)
The following PHP code goes under wp-content/plugins/exampleplugin/exampleplugin.php
:
<?php
/**
* @package ExamplePlugin
* @version 1.0
*/
/*
Plugin Name: ExamplePlugin
Plugin URI: http://example.com/
Description: Custom
Author: ExamplePlugin
Version: 1.0
Author URI: http://example.com/
*/
function enqueue_block_editor_adjustments() {
wp_register_script(
'block_editor_adjustments',
plugin_dir_url( __FILE__ ) . 'block_editor_adjustments.js',
[ 'wp-blocks', 'wp-dom', 'wp-dom-ready', 'wp-edit-post' ],
filemtime( plugin_dir_path( __FILE__ ) . 'block_editor_adjustments.js' )
);
wp_enqueue_script( 'block_editor_adjustments' );
}
add_action( 'enqueue_block_editor_assets', 'enqueue_block_editor_adjustments' );
The above adds our custom Javascript file in the editor.
And here is the wp-content/plugins/exampleplugin/block_editor_adjustments.js
file:
// Register our property at core/heading
wp.hooks.addFilter(
'blocks.registerBlockType',
'ExamplePlugin/block_editor_adjustments', // our custom namespace
function(settings, name) {
if (name !== 'core/heading') { // skip other core blocks
return settings;
}
settings.attributes = Object.assign(settings.attributes, {
showInTableOfContents: { // showInTableOfContents is our property name
type: 'boolean',
default: false
}
});
return settings;
}
);
// Display the custom ToggleControl for every header; toggle the custom property
wp.hooks.addFilter(
'editor.BlockEdit',
'ExamplePlugin/block_editor_adjustments',
wp.compose.createHigherOrderComponent(function(BlockEdit) {
return function(props) {
if (props.name !== 'core/heading') { // skip other core blocks
return wp.element.createElement( BlockEdit, props );
}
console.log('here are the props', props);
return wp.element.createElement(
wp.element.Fragment,
{},
wp.element.createElement( BlockEdit, props ),
wp.element.createElement(
wp.blockEditor.InspectorControls,
{},
wp.element.createElement(
wp.components.PanelBody,
{},
wp.element.createElement(
wp.components.ToggleControl,
{
label: 'Show in Table of Contents',
checked: props.attributes.showInTableOfContents,
onChange: ( value ) => {
props.setAttributes( { showInTableOfContents: value } );
},
}
)
)
)
);
};
})
);
// Convert the custom property value into CSS class name on every save
wp.hooks.addFilter(
'blocks.getSaveContent.extraProps',
'ExamplePlugin/block_editor_adjustments',
function(extraProps, blockType, attributes) {
if (blockType.name !== 'core/heading') { // skip other core blocks
return extraProps;
}
if (attributes.showInTableOfContents) {
extraProps.className = extraProps.className + ' fq_contents_header';
}
return extraProps;
}
);
General idea and guidance:
- https://mariecomet.fr/en/2021/12/14/adding-options-controls-existing-gutenberg-block/
- https://github.com/MarieComet/core-block-custom-attributes/blob/main/src/attributes/sidebarSelect.js
Documentation:
addFilter()
syntaxblocks.registerBlockType
hookeditor.BlockEdit
hookwp.element.createElement()
wp.compose.createHigherOrderComponent()
ToggleControl
documentation
Other, helpful:
- https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-supports-in-static-blocks/ shows that edit and save callbacks can be potentially defined right inside registerBlockType, but I cgot stuck at BlockEdit not being available
- the above approach is in this OP code https://wordpress.stackexchange.com/questions/346612/how-to-get-the-togglecontrol-gutenberg-component-working-for-a-php-block and the answer shows the working ToggleControl example
- https://github.com/WordPress/gutenberg/issues/20213
- https://awhitepixel.com/blog/add-custom-settings-to-existing-wordpress-gutenberg-blocks/
editor.BlockEdit
+blocks.getSaveContent.extraProps
usage example