WordPress.org

WordPress Developer Blog

Snippet: How to lock WordPress blocks and prevent unlocking

Snippet: How to lock WordPress blocks and prevent unlocking

The Block Locking API in WordPress allows developers to control block editing by restricting movement and removal. This API is ideal for maintaining design consistency in templates and patterns while still allowing users to customize other elements of the content.

Locking blocks

As the image above shows, you can lock blocks directly through the Editor’s user interface (UI). However, you can also lock blocks programmatically using the lock attribute in the block’s markup. For example:

<!-- wp:paragraph {"lock":{"move":true,"remove":true}} -->
    <p>This Paragraph block is locked and cannot be moved or deleted.</p>
<!-- /wp:paragraph -->

In this markup, move: true prevents the block from being moved, and remove: true stops it from being deleted. This method is particularly useful when building templates and patterns in a theme or plugin.

Preventing unlocking

While the Block Locking API is useful for ensuring design consistency, any user can lock and unlock blocks by default, which may not always be desirable. The canLockBlocks setting in the Editor controls this functionality.

You can disable the UI for locking and unlocking globally by setting canLockBlocks to false using the block_editor_settings_all PHP filter:

add_filter( 'block_editor_settings_all', function( $settings, $context ) {
    $settings['canLockBlocks'] = false; // Disable locking/unlocking for all users

    return $settings;
}, 10, 2 );

If you want more control, such as only preventing non-administrators from unlocking blocks while editing posts, you can add conditional logic:

add_filter( 'block_editor_settings_all', function( $settings, $context ) {
    if ( 
        isset( $context->post ) && 
        'post' === $context->post->post_type && 
        ! current_user_can( 'edit_theme_options' ) 
    ) {
        $settings['canLockBlocks'] = false; // Disable locking/unlocking for non-administrators editing posts
    }

    return $settings;
}, 10, 2 );

Here’s an explanation of the conditionals:

  • $context->post: Ensures the filter is running in the context of a specific post. This code is not designed for the Site Editor.
  • 'post' === $context->post->post_type: Limits the restriction to the post post type.
  • ! current_user_can( 'edit_theme_options' ): Checks if the current user does not have the edit_theme_options capability, which only administrators have by default.

Disabling the Code Editor

While setting canLockBlocks to false disables the locking UI, users could still technically open the Code Editor and remove the lock attribute from locked blocks. You can also disable the Code Editor using the codeEditingEnabled setting to prevent this.

add_filter( 'block_editor_settings_all', function( $settings, $context ) {
    if ( 
        isset( $context->post ) && 
        'post' === $context->post->post_type && 
        ! current_user_can( 'edit_theme_options' ) 
    ) {
        $settings['canLockBlocks'] = false; // Disable locking/unlocking for non-administrators editing posts.
        $settings[ 'codeEditingEnabled' ] = false; // Disable access to the Code Editor.    
    }

    return $settings;
}, 10, 2 );

Add the code to your theme’s functions.php file or a custom plugin to use this snippet.

Additional resources

Props to @bph and @welcher for reviewing this snippet and providing feedback.

Leave a Reply

Your email address will not be published. Required fields are marked *