Miscellaneous Editor Changes in WordPress 6.9

BlockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. Variations: Have getActiveBlockVariation fall back to default variation

WordPress 6.9 introduces a small change to active block variation detection.

To understand what that change looks like, recall that a block variation can include an isActive criterion that will be used to determine if a given block instance matches the variation.

The change concerns the case in which none of the isActive criteria of a block type’s variations match a given block instance. In this case, WordPress 6.9 will use the variation with the isDefault property set to true as fallback, if any.

Two limitations apply:

  1. The variation with the isDefault property is only used as fallback if it doesn’t also include an isActive criterion, as that would mean that the variation did not match that criterion (and thus cannot be assumed to be active).
  2. The fallback is only applied for the block and transform scopes but not to the inserter, as to not affect the block name displayed there.

In practice, the updated behavior should be consistent with users’ and developers’ expectations, as the isDefault variation is typically used to set a default block variation different from the “vanilla” block type.

Together with the improvements made to active block variation detection in WordPress 6.6 , this change allows block authors to express the criteria for active block detection in a very succinct and JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML.-only manner. For an example, see how these principles were applied to rewrite Group block variations.

CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.-data: Media Entity Deprecation

What is being deprecated?

In WordPress 6.9, the @wordpress/core-data package’s media entity is being deprecated. This entity is usually accessed through a range of APIs:

  • The getMedia and getMediaItems selectors or resolvers.
  • The saveMedia and deleteMedia actions.
  • The getEntityRecordgetEntityRecords and other selectors or resolvers when passed the 'root' and 'media' params (e.g. getEntityRecords( 'root', 'media' );).
  • The editEntityRecordsaveEntityRecorddeleteEntityRecord and other actions when passed the 'root' and 'media' params (e.g. deleteEntityRecord( 'root', 'media', 123)).

These APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. calls will continue to work in WordPress 6.9, but will now log a deprecation message that recommends switching to a different signature.

Why is this being deprecated?

The media entity was found to be duplicating another entity, attachment. This attachment entity is usually accessed through API calls like getEntityRecords( 'postType', 'attachment' );. These two entities both internally use the media REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. endpoint and return results for attachment post types.

The entity system maintains a cache of REST API data, and the two separate entity types result in two separate caches that might contain different states for the same data. If the caches become desynchonized, this can result in noticeable bugs where a user interface might show outdated data, or old data overwrites newer data when saved.

Various solutions for fixing this issue were explored, but the option that was found to be safest was to deprecate the media entity in favor of the attachment entity.

How to update your code to use the attachment entity

Replacing API calls

The following code snippet shows some examples of how to update your API calls:

wp.data.select( 'core' ).getMedia( 123 ); // now deprecated
wp.data.select( 'core' ).getEntityRecord( 'root', 'media', 123 ); // now deprecated
wp.data.select( 'core' ).getEntityRecord( 'postType', 'attachment', 123 ); // recommended update

wp.data.select( 'core' ).getMediaItems(); // now deprecated
wp.data.select( 'core' ).getEntityRecords( 'root', 'media' ); // now deprecated
wp.data.select( 'core' ).getEntityRecords( 'postType', 'attachment' ); // recommended update

wp.data.dispatch( 'core' ).saveMedia( 123, { // ... media data } ); // now deprecated
wp.data.dispatch( 'core' ).saveEntityRecord( 'root', 'media', 123, { // ... media data } ); // now deprecated
wp.data.dispatch( 'core' ).saveEntityRecord( 'postType', 'attachment', 123,  { // ... media data } ); // recommended update

wp.data.dispatch( 'core' ).deleteMedia( 123 ); // now deprecated
wp.data.dispatch( 'core' ).deleteEntityRecord( 'root', 'media', 123 ); // now deprecated
wp.data.dispatch( 'core' ).deleteEntityRecord( 'postType', 'attachment', 123 ); // recommended update
Changes to the caption property when using the getEditedEntityRecord selector

When making an API call for the ‘edited’ version of an entity record (e.g. getEditedEntityRecord( 'root', 'media', 123 )), the core data package converts the caption property to a string:

caption: "My image's caption"

The attachment entity doesn’t perform the same processing, an API call like getEditedEntityRecord( 'postType', 'attachment', 123 ) returns the caption in its object form:

caption: {
    raw: "My image's caption",
    rendered: "My image's caption"
}

The caption.raw property corresponds to the string value that the media entity returns for the caption.

When switching to the ‘attachment’ entity, some code may need to be updated to account for this difference.

Block Editor: Support passing updater function to setAttributes

Starting from WordPress 6.9, the setAttribute prop passed to a block’s Edit component will now support an updater function as an argument.

The updater is a pure function; it takes only the current attributes as its argument and returns the updated attributes.

// Toggle a setting when the user clicks the button.
const toggleSetting = () =>
	setAttributes( ( currentAttr ) => ( {
		mySetting: ! currentAttr.mySetting,
	} ) );

// Append item to the list.
const addListItem = ( newListItem ) =>
	setAttributes( ( currentAttr ) => ( {
		list: [ ...currentAttr.list, newListItem ],
	} ) );

SelectControl: Moved class names to the component root

The SelectControl component’s class assignments have been adjusted for better consistency with other form components, such as TextControl. Both the default class name (components-select-control) and any custom class name passed via the className prop are now applied to the root element of the component, rather than to the internal element.

While this update does not alter the component’s behavior or visual design, custom CSSCSS Cascading Style Sheets. that previously depended on the inner structure may need to be updated.

Before:

<div class="components-base-control">
  <div class="components-base-control__field">
    <div class="components-flex components-input-base components-select-control my-custom-classname">
      <div class="components-flex-item">
        <label class="components-truncate components-text components-input-control__label">Label</label>
      </div>
      <div class="components-input-control__container">
        <select class="components-select-control__input"></select>
        <div aria-hidden="true" class="components-input-control__backdrop"></div>
      </div>
    </div>
  </div>
</div>

After:

<div class="components-base-control components-select-control my-custom-classname">
  <div class="components-base-control__field">
    <div class="components-flex components-input-base">
      <div class="components-flex-item">
        <label class="components-truncate components-text components-input-control__label">Label</label>
      </div>
      <div class="components-input-control__container">
        <select class="components-select-control__input"></select>
        <div aria-hidden="true" class="components-input-control__backdrop"></div>
      </div>
    </div>
  </div>
</div>

Registering custom social icons

WordPress 6.9 adds support for registering custom social icons to the Social Icons block. With this update, developers can create plugins to define new services and SVGs, and expose them to both the editor and frontend through block variations and PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher filters. For styling, matching brand colors can be handled in CSS and loaded for both views.

Example for Ko-fi variation:

registerBlockVariation('core/social-link', {
	name: 'kofi',
	title: 'Ko-fi',
	icon: (
		<SVG role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
			<Path d="M11.351 2.715c-2.7 0-4.986.025-6.83.26C2.078 3.285 0 5.154 0 8.61c0 3.506.182 6.13 1.585 8.493 1.584 2.701 4.233 4.182 7.662 4.182h.83c4.209 0 6.494-2.234 7.637-4a9.5 9.5 0 0 0 1.091-2.338C21.792 14.688 24 12.22 24 9.208v-.415c0-3.247-2.13-5.507-5.792-5.87-1.558-.156-2.65-.208-6.857-.208m0 1.947c4.208 0 5.09.052 6.571.182 2.624.311 4.13 1.584 4.13 4v.39c0 2.156-1.792 3.844-3.87 3.844h-.935l-.156.649c-.208 1.013-.597 1.818-1.039 2.546-.909 1.428-2.545 3.064-5.922 3.064h-.805c-2.571 0-4.831-.883-6.078-3.195-1.09-2-1.298-4.155-1.298-7.506 0-2.181.857-3.402 3.012-3.714 1.533-.233 3.559-.26 6.39-.26m6.547 2.287c-.416 0-.65.234-.65.546v2.935c0 .311.234.545.65.545 1.324 0 2.051-.754 2.051-2s-.727-2.026-2.052-2.026m-10.39.182c-1.818 0-3.013 1.48-3.013 3.142 0 1.533.858 2.857 1.949 3.897.727.701 1.87 1.429 2.649 1.896a1.47 1.47 0 0 0 1.507 0c.78-.467 1.922-1.195 2.623-1.896 1.117-1.039 1.974-2.364 1.974-3.897 0-1.662-1.247-3.142-3.039-3.142-1.065 0-1.792.545-2.338 1.298-.493-.753-1.246-1.298-2.312-1.298"/>
		</SVG>
	),
	attributes: {
		service: 'kofi',
	},
	isActive: ['service']
});

Filters and CSS support synchronization with the frontend output. For more comprehensive references and setup routines, see this Developer Blog post.


Props to content authors @bernhard-reiter, @greenshady, @mamaduka, @talldanwp, @wildworks

6-9, #dev-notes, #dev-notes-6-9