Block Locking
The Block Locking API was introduced in WordPress 5.9. With it blocks can be locked from being able to get moved and or removed from the editor. In WordPress 6.0 this API got a visual user interface so that editors can lock and unlock blocks themselves.
Blocks can opt out of showing the block locking UI to the user via the lock
block supports option. There also is a way to override what users are able to use the block locking UI via the canLockBlocks
editor setting.
Locking the ability to remove / move a block
Individual blocks can lock down their ability to be moved and or removed. This is done via an attribute that is added by WordPress to every single block called lock
. The lock
attribute is an object that accepts two properties: move
and remove
. Both of them are Boolean
values. There is no UI to control the lock state of a block. It can only be controlled via code.
In a pattern you can set these attributes via the html comment of the block where you can set its attributes.
<!-- wp:columns -->
<div class="wp-block-columns">
<!-- wp:column { "lock": { "move": false, "remove": false } } -->
<div class="wp-block-column">
...
</div>
<!-- /wp:column -->
<!-- wp:column { "lock": { "move": false, "remove": false } } -->
<div class="wp-block-column">
...
</div>
<!-- /wp:column -->
</div>
<!-- /wp:columns -->
You can also use these attributes in your custom blocks to set default values for the locking. For example if you have a page header block that should never get removed you can set the default value of the lock
attribute to { remove: true }
Restricting which inner blocks can be used
The core column, group, and cover block support the ability to restrict which blocks are allowed within the inner blocks area. This is being done via two attributes that exist on these blocks. The allowedBlocks
and templateLock
attributes can be set via the html comment in patterns to restrict which blocks can be inserted within a specific pattern. And with the ability to also define a templateLock
you can even make it so that editors cannot move or remove any of the children within a column for example.
<!-- wp:columns -->
<div class="wp-block-columns">
<!-- wp:column { "allowedBlocks": [ "core/image" ], "templateLock": "all" } } -->
<div class="wp-block-column">
...
</div>
<!-- /wp:column -->
<!-- wp:column { "allowedBlocks": [ "core/heading", "core/paragraph" ], "templateLock": "all" } } -->
<div class="wp-block-column">
...
</div>
<!-- /wp:column -->
</div>
<!-- /wp:columns -->
Since these patterns are php files you can make the allowedBlocks
list filterable via an apply_filters
hook.
Disabling the block locking UI
For a specific block
If you have a block that should not expose the block locking UI to any user you can opt out of it on a block level by setting the supports.lock
option to false.
{
"name": "namespace/block",
"title": "Example",
"supports": {
"lock": false
}
}
Override block locking UI setting
There are many circumstances where block locking should actually be used to prevent certain users from changing a locked section. By filtering the block_editor_settings_all
you can override which users should be able to use the block locking UI altogether.
add_filter(
'block_editor_settings_all',
static function( $settings, $context ) {
// Allow for the Editor role and above.
$settings['canLockBlocks'] = current_user_can( 'delete_others_posts' );
// Only enable for specific user(s).
$user = wp_get_current_user();
if ( in_array( $user->user_email, array( 'george@example.com' ), true ) ) {
$settings['canLockBlocks'] = false;
}
// Disable for posts/pages.
if ( $context->post && $context->post->post_type === 'page' ) {
$settings['canLockBlocks'] = false;
}
return $settings;
},
10,
2
);