WARNING: There be dragons ahead
Changing the allowed innerblocks of the core/buttons
block can be done, but it will make your life harder and introduce lots of new problems.
Note that it would be faster, easier, and safer to implement a new buttons block that only accepts your custom block.
To do this you would need to:
- wait until the editor is ready using the editor promise on the window object that it uses to initialise things
- this also means that when your code loads is important.
- filter all blocks and check their registration settings to see if they require a
core/buttons
block as their parent.wp.blocks.getBlockTypes()
orimport { getBlockTypes } from '@wordpress/blocks';
will be useful here- if one is found, take it’s settings and re-register that block minus
core/buttons
as a parent usingregisterBlockType
fromimport { registerBlockType } from '@wordpress/blocks';
orwp.blocks
- if it’s the
core/button
block, modify its settings so that it does not support the inserter. Unregistering it can cause the editor to crash ( see below point ).- the only way you can unregister a block safely is before the editor is initialised, ideally in PHP by declaring it is not allowed via filters.
- WARNING: Do not try to unregister the block type!! You cannot safely unregister blocks after the editor has been initialised, if you do this and there is an instance of that block in the editor the block editor will crash and require a hard refresh to recover.
- if one is found, take it’s settings and re-register that block minus
You will need to use the main window.wp
object to interact with the block registry, or use the equivalents from the respective packages in your bundle. The readme’s for each package should help indicate this. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-blocks/, and inspect window.wp.blocks
Caveats:
- existing button blocks inside core button blocks will not be removed
- block patterns that use
core/button
withcore/buttons
will sidestep all of this - nothing stops them from copy pasting a
core/button
andcore/buttons
combination into your editor - other plugins that add their own blocks or variations will either be broken, or break your setup
- doing this will slow down your editor, and may be a fragile operation.
- There is a high chance this will break in the future as the block editor improves and new features are added. E.g. the upcoming block hooks feature may cause problems here
There is also an option where you can use a filter to replace the edit component, enabling you to use the allowed blocks attribute to force only yours to be selectable, but this too has similar caveats, can fail catastrophically if not done correctly, and requires you to fork the majority of the core/buttons
block anyway defeating the point.
Note that of all the options and methods to satisfy your clients requirement, this route is the most difficult, extreme, and least robust/reliable option. It should be considered as an extreme last resort, not a time/effort saving measure (it will save neither).
Other options included:
- A block style for the
core/buttons
block that hides allcore/button
blocks using CSS- A PHP render filter could also have removed them so they never appeared in the HTML at all
- Forking
core/buttons
- Creating your own
FbnKlmn/buttons
block - Adding an icons attribute to
core/button
instead of creating a new block - Asking how to make the core version of the button block meet the requirements instead of creating a brand new block
What You Should Do Instead
Literally anything else.
Trying to enforce up the chain what children a parent block can choose is a mistake. Instead:
- Register a block variation for
core/buttons
- Given it a name that matches your requirements
- Use the Innerblocks parameter to include one of your custom buttons by default, note that this doesn’t prevent
core/button
being added. - Set it to the default variation so that
core/buttons
are this variation by default - Hide child blocks that don’t meet your criteria when they are children of this variation using the classnames WP adds to the markup.
Likewise, a block variation of core/button
would be the way to customize the core block without creating a brand new block. There are other ways of doing this without doing what you asked for that are easier than what you asked for, but this would be my approach.
E.g. for icons, filter the core/button
block to add an icon attribute, either a string from a predefined list or an attachment ID, then filter the edit component to add a control for it. The icon can then be added via an :after
or :before
pseudo-element on the frontend, or if you’re feeling adventurous via a PHP render filter that modifies the markup. If the client ever migrated the content, or imported it from elsewhere then everything would fallback gracefully or be migrated across without transforms for free