Skip to content

Commit

Permalink
Break out the Curating the Editor Experience doc into its own How-to …
Browse files Browse the repository at this point in the history
…Guides section (#57289)

* Break out into individual docs.

* Update the new pages.

* Add the manifest and toc.

* Remove broken link.

* Add links.

* Clarify intro.
  • Loading branch information
ndiego authored Dec 27, 2023
1 parent b46686e commit 53f7f20
Show file tree
Hide file tree
Showing 9 changed files with 643 additions and 461 deletions.
459 changes: 0 additions & 459 deletions docs/how-to-guides/curating-the-editor-experience.md

This file was deleted.

25 changes: 25 additions & 0 deletions docs/how-to-guides/curating-the-editor-experience/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Curating the Editor Experience

Curating the editing experience in WordPress is important because it allows you to streamline the editing process, ensuring consistency and alignment with the site's style and branding guidelines. It also makes it easier for users to create and manage content effectively without accidental modifications or layout changes. This leads to a more efficient and personalized experience.

The purpose of this guide is to offer various ways you can lock down and curate the experience of using WordPress, especially with the introduction of more design tools and the Site Editor.

In this section, you will learn:

1. [**Block locking**](https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/block-locking): how to restrict user interactions with specific blocks in the Editor for better content control
1. [**Patterns**](https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/patterns): about creating and implementing predefined block layouts to ensure design and content uniformity
1. [**theme.json**](https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/theme-json): to configure global styles and settings for your theme using the theme.json file
1. [**Filters and hooks**](https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/filters-and-hooks): about the essential filters and hooks used to modify the Editor
1. [**Disabling Editor functionality**](https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/disable-editor-functionality): about additional ways to selectively disable features or components in the Editor to streamline the user experience

## Combining approaches

Remember that the approaches provided in the documentation above can be combined as you see fit. For example, you can provide custom patterns to use when creating a new page while also limiting the amount of customization that can be done to aspects of them, like only allowing specific preset colors to be used for the background of a Cover block or locking down what blocks can be deleted.

When considering the approaches to take, think about the specific ways you might want to both open up the experience and curate it.

## Additional resources

- [Builder Basics – Working with Templates in Full Site Editing (Part 3)](https://wordpress.tv/2022/05/24/nick-diego-builder-basics-working-with-templates-in-full-site-editing-part-3/)
- [Core Editor Improvement: Curated experiences with locking APIs & theme.json](https://make.wordpress.org/core/2022/02/09/core-editor-improvement-curated-experiences-with-locking-apis-theme-json/)
- [Learn WordPress session on Curating the Editor Experience](https://wordpress.tv/2022/07/22/nick-diego-curating-the-editor-experience/)
69 changes: 69 additions & 0 deletions docs/how-to-guides/curating-the-editor-experience/block-locking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Block Locking API

The Block Locking API allows you to restrict actions on specific blocks within the Editor. This API can be used to prevent users from moving, removing, or editing certain blocks, ensuring layout consistency and content integrity.

## Lock the ability to move or remove specific blocks

Users can lock and unlock blocks via the Editor. The locking UI has options for preventing blocks from being moved within the content canvas or removed:

![Image of locking interface](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/Locking%20interface.png?raw=true)

Keep in mind that you can apply locking options to blocks nested inside of a containing block by turning on the "Apply to all blocks inside" option. However, you cannot mass lock blocks otherwise.

## Lock the ability to edit certain blocks

Alongside the ability to lock moving or removing blocks, the [Navigation Block](https://github.com/WordPress/gutenberg/pull/44739) and [Reusable block](https://github.com/WordPress/gutenberg/pull/39950) have an additional capability: lock the ability to edit the contents of the block. This locks the ability to make changes to any blocks inside of either block type.

## Apply block locking to patterns or templates

When building patterns or templates, theme authors can use these same UI tools to set the default locked state of blocks. For example, a theme author could lock various pieces of a header. Keep in mind that by default, users with editing access can unlock these blocks. [Here’s an example of a pattern](https://gist.github.com/annezazu/acee30f8b6e8995e1b1a52796e6ef805) with various blocks locked in different ways and here’s more context on [creating a template with locked blocks](https://make.wordpress.org/core/2022/02/09/core-editor-improvement-curated-experiences-with-locking-apis-theme-json/). You can build these patterns in the Editor itself, including adding locking options, before following the [documentation to register them](/docs/reference-guides/block-api/block-patterns.md).

## Apply content-only editing in patterns or templates

This functionality was introduced in WordPress 6.1. In contrast to block locking, which disables the ability to move or remove blocks, content-only editing is both designed for use at the pattern or template level and hides all design tools, while still allowing for the ability to edit the content of the blocks. This provides a great way to simplify the interface for users and preserve a design. When this option is added, the following changes occur:

- Non-content child blocks (containers, spacers, columns, etc) are hidden from list view, un-clickable on the canvas, and entirely un-editable.
- The Inspector will display a list of all child 'content' blocks. Clicking a block in this list reveals its settings panel.
- The main List View only shows content blocks, all at the same level regardless of actual nesting.
- Children blocks within the overall content locked container are automatically move / remove locked.
- Additional child blocks cannot be inserted, further preserving the design and layout.
- There is a link in the block toolbar to ‘Modify’ that a user can toggle on/off to have access to the broader design tools. Currently, it's not possibly to programmatically remove this option.

This option can be applied to Columns, Cover, and Group blocks as well as third-party blocks that have the templateLock attribute in its block.json. To adopt this functionality, you need to use `"templateLock":"contentOnly"`. [Here's an example of a pattern](https://gist.github.com/annezazu/d62acd2514cea558be6cea97fe28ff3c) with this functionality in place. For more information, please [review the relevant documentation](/docs/reference-guides/block-api/block-templates.md#locking).

Note: There is no UI in place to manage content locking and it must be managed at the code level.

## Change permissions to control locking ability

Agencies and plugin authors can offer an even more curated experience by limiting which users have [permission to lock and unlock blocks](https://make.wordpress.org/core/2022/05/05/block-locking-settings-in-wordpress-6-0/). By default, anyone who is an administrator will have access to lock and unlock blocks.

Developers can add a filter to the [block_editor_settings_all](https://developer.wordpress.org/reference/hooks/block_editor_settings_all/) hook to configure permissions around locking blocks. The hook passes two parameters to the callback function:

- `$settings` - An array of configurable settings for the Editor.
- `$context` - An instance of WP_Block_Editor_Context, an object that contains information about the current Editor.

Specifically, developers can alter the `$settings['canLockBlocks']` value by setting it to `true` or `false`, typically by running through one or more conditional checks.

The following example disables block locking permissions for all users when editing a page:

```php
add_filter( 'block_editor_settings_all', function( $settings, $context ) {
if ( $context->post && 'page' === $context->post->post_type ) {
$settings['canLockBlocks'] = false;
}

return $settings;
}, 10, 2 );
```

Another common use case may be to only allow users who can edit the visual design of the site (theme editing) to lock or unlock blocks. Now, the best option would be to test against the `edit_theme_options` capability, as shown in the following code snippet:

```php
add_filter( 'block_editor_settings_all', function( $settings ) {
$settings['canLockBlocks'] = current_user_can( 'edit_theme_options' );

return $settings;
} );
```

Developers may use any type of conditional check to determine who can lock/unlock blocks. This is merely a small sampling of what is possible via the filter hook.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
## Disable Editor functionality

This page is dedicated to the many ways you can disable specific functionality in the Post Editor and Site Editor that are not covered in other areas of the curation documentation.

## Restrict block options

There might be times when you don’t want access to a block at all to be available for users. To control what’s available in the inserter, you can take two approaches: [an allow list](/docs/reference-guides/filters/block-filters.md#using-an-allow-list) that disables all blocks except those on the list or a [deny list that unregisters specific blocks](/docs/reference-guides/filters/block-filters.md#using-a-deny-list).

## Disable the Pattern Directory

To fully remove patterns bundled with WordPress core from being accessed in the Inserter, the following can be added to your `functions.php` file:

```php
function example_theme_support() {
remove_theme_support( 'core-block-patterns' );
}
add_action( 'after_setup_theme', 'example_theme_support' );
```

## Disable block variations

Some Core blocks are actually [block variations](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). A great example is the Row and Stack blocks, which are actually variations of the Group block. If you want to disable these "blocks", you actually need to disable the respective variations.

Block variations are registered using JavaScript and need to be disabled with JavaScript. The code below will disable the Row variation.

```js
wp.domReady( () => {
wp.blocks.unregisterBlockVariation( 'core/group', 'group-row' );
});
```

Assuming the code was placed in a `disable-variations.js` file located in the root of your theme folder, you can enqueue this file in the theme's `functions.php` using the code below.

```php
function example_disable_variations_script() {
wp_enqueue_script(
'example-disable-variations-script',
get_template_directory_uri() . '/disable-variations.js',
array( 'wp-dom-ready' ),
wp_get_theme()->get( 'Version' ),
true
);
}
add_action( 'enqueue_block_editor_assets', 'example_disable_variations_script' );
```

## Disable block styles

There are a few Core blocks that include their own [block styles](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/). An example is the Image block, which includes a block style for rounded images called "Rounded". You many not want your users to round images, or you might prefer to use the border-radius control instead of the block style. Either way, it's easy to disable any unwanted block styles.

Unlike block variations, you can register styles in either JavaScript or PHP. If a style was registered in JavaScript, it must be disabled with JavaScript. If registered using PHP, the style can be disabled with either. All Core block styles are registed in JavaScript.

So, you would use the following code to disable the "Rounded" block style for the Image block.

```js
wp.domReady( () => {
wp.blocks.unregisterBlockStyle( 'core/image', 'rounded' );
});
```

This JavaScript should be enqueued much like the block variation example above. Refer to the [block styles](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/) documentation for how to register and unregister styles using PHP.

## Disable access to the Template Editor

Whether you’re using theme.json in a Classic or Block theme, you can add the following to your `functions.php` file to remove access to the Template Editor that is available when editing posts or pages:

```php
function example_theme_support() {
remove_theme_support( 'block-templates');
}
add_action( 'after_setup_theme', 'example_theme_support' );
```

This prevents both the ability to create new block templates or edit them from within the Post Editor.

## Disable access to the Code Editor

The Code Editor allows you to view the underlying block markup for a page or post. While this view is handy for experienced users, you can inadvertently break block markup by editing content. Add the following to your `functions.php` file to restrict access.

```php
function example_restrict_code_editor_access( $settings, $context ) {
$settings[ 'codeEditingEnabled' ] = false;

return $settings;
}
add_filter( 'block_editor_settings_all', 'example_restrict_code_editor_access', 10, 2 );
```

This code prevents all users from accessing the Code Editor. You could also add [capability](https://wordpress.org/documentation/article/roles-and-capabilities/) checks to disable access for specific users.
109 changes: 109 additions & 0 deletions docs/how-to-guides/curating-the-editor-experience/filters-and-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Filters and hooks

The Editor provides numerous filters and hooks that allow you to modify the editing experience. Here are a few.

## Server-side theme.json filters

The theme.json file is a great way to control interface options, but it only allows for global or block-level modifications, which can be limiting in some scenarios.

For instance, in the previous section, color and typography controls were disabled globally using theme.json. But let's say you want to enable color settings for users who are Administrators.

To provide more flexibility, WordPress 6.1 introduced server-side filters allowing you to customize theme.json data at four different data layers.

- [`wp_theme_json_data_default`](https://developer.wordpress.org/reference/hooks/wp_theme_json_data_default/) - Hooks into the default data provided by WordPress
- [`wp_theme_json_data_blocks`](https://developer.wordpress.org/reference/hooks/wp_theme_json_data_blocks/) - Hooks into the data provided by blocks.
- [`wp_theme_json_data_theme`](https://developer.wordpress.org/reference/hooks/wp_theme_json_data_theme/) - Hooks into the data provided by the current theme.
- [`wp_theme_json_data_user`](https://developer.wordpress.org/reference/hooks/wp_theme_json_data_user/) - Hooks into the data provided by the user.

In the following example, the data from the current theme's theme.json file is updated using the `wp_theme_json_data_theme` filter. Color controls are restored if the current user is an Administrator.

```php
// Disable color controls for all users except Administrators.
function example_filter_theme_json_data_theme( $theme_json ){
$is_administrator = current_user_can( 'edit_theme_options' );

if ( $is_administrator ) {
$new_data = array(
'version' => 2,
'settings' => array(
'color' => array(
'background' => true,
'custom' => true,
'customDuotone' => true,
'customGradient' => true,
'defaultGradients' => true,
'defaultPalette' => true,
'text' => true,
),
),
);
}

return $theme_json->update_with( $new_data );
}
add_filter( 'wp_theme_json_data_theme', 'example_filter_theme_json_data_theme' );
```

The filter receives an instance of the `WP_Theme_JSON_Data class` with the data for the respective layer. Then, you pass new data in a valid theme.json-like structure to the `update_with( $new_data )` method. A theme.json version number is required in `$new_data`.


## Client-side (Editor) filters

WordPress 6.2 introduced a new client-side filter allowing you to modify block-level [theme.json settings](/docs/reference-guides/theme-json-reference/theme-json-living.md#settings) before the Editor is rendered.

The filter is called `blockEditor.useSetting.before` and can be used in the JavaScript code as follows:

```js
import { addFilter } from '@wordpress/hooks';

/**
* Limit the Column block's spacing options to pixels.
*/
addFilter(
'blockEditor.useSetting.before',
'example/useSetting.before',
( settingValue, settingName, clientId, blockName ) => {
if ( blockName === 'core/column' && settingName === 'spacing.units' ) {
return [ 'px' ];
}
return settingValue;
}
);
```

This example will restrict the available spacing units for the Column block to just pixels. As discussed above, a similar restriction could be applied using theme.json filters or directly in a theme’s theme.json file using block-level settings.

However, the `blockEditor.useSetting.before` filter is unique because it allows you to modify settings according to the block’s location, neighboring blocks, the current user’s role, and more. The possibilities for customization are extensive.

In the following example, text color controls are disabled for the Heading block whenever the block is placed inside of a Media & Text block.

```js
import { select } from '@wordpress/data';
import { addFilter } from '@wordpress/hooks';

/**
* Disable text color controls on Heading blocks when placed inside of Media & Text blocks.
*/
addFilter(
'blockEditor.useSetting.before',
'example/useSetting.before',
( settingValue, settingName, clientId, blockName ) => {
if ( blockName === 'core/heading' ) {
const { getBlockParents, getBlockName } = select( 'core/block-editor' );
const blockParents = getBlockParents( clientId, true );
const inMediaText = blockParents.some( ( ancestorId ) => getBlockName( ancestorId ) === 'core/media-text' );

if ( inMediaText && settingName === 'color.text' ) {
return false;
}
}

return settingValue;
}
);
```

## Additional resources

- [How to modify theme.json data using server-side filters](https://developer.wordpress.org/news/2023/07/05/how-to-modify-theme-json-data-using-server-side-filters/) (WordPress Developer Blog)
- [Curating the Editor experience with client-side filters](https://developer.wordpress.org/news/2023/05/24/curating-the-editor-experience-with-client-side-filters/) (WordPress Developer Blog)
Loading

0 comments on commit 53f7f20

Please sign in to comment.