Editor Components updates in WordPress 6.1

This post lists notable changes to the @wordpress/components package for the WordPress 6.1 release:

Updated 26 October: (@mciampini):

  • deleted the statement about the anchorRefanchorRect, getAnchorRect and __unstableShift props being scheduled for removal in the Popover component. The related deprecation messaged will be updated in the WordPress 6.1.1 release;
  • deleted the statement about the useAnchorRef hook being scheduled for removal. The related deprecation messaged will be updated in the WordPress 6.1.1 release;
  • added a statement about the removal of the range prop in the Popover component.

Changes to the Popover component

The Popover component from the @wordpress/components package has been almost entirely rewritten, in an effort to make it more stable, more reliable and more performant.

Below is a list with the main 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. changes:

  • a new placement prop has been introduced. This prop is meant to replace the legacy position prop (which will be marked as deprecated in the near future);
  • a new anchor prop has been introduced. This prop is meant to replace all previous anchor-related props (anchorRefanchorRectgetAnchorRect). These older anchor-related props are now marked as deprecated;
  • the __unstableForcePosition prop has been marked as deprecated, in favor of new flip and resize props. The __unstableForcePosition is currently scheduled for removal in WordPress 6.3;
  • the __unstableObserveElement prop has been removed, since it’s not necessary anymore after the recent updates to the Popover;
  • the range prop has been removed, as it hasn’t been having any effects on the component for a while.

For more details, view the updated component’s README and the Storybook examples and interactive docs.

The changes to the Popover component also affected the @wordpress/rich-text package, where a new useAnchor hook was introduced. The older useAnchorRef hook has been marked as deprecated.

For more information visit #43691, #43845, #43546, #43617, #44195 and #45195(top)

Preparing CustomSelectControl to take up the entire width of its parent.

To improve consistency with SelectControl, the CSSCSS Cascading Style Sheets. styles for CustomSelectControl will be changed to take up the full width available, regardless of how short the option strings are. To start opting into these new unconstrained width styles, set the __nextUnconstrainedWidth prop to true. These styles will become the default in 6.4.

To keep your CustomSelectControl similar to the previous styling, add width constraints to a wrapper div.

.my-custom-select-control-wrapper {
  width: fit-content;
  min-width: 130px;
}
<div className="my-custom-select-control-wrapper">
  <CustomSelectControl __nextUnconstrainedWidth />
</div>

For more information visit #43230.

Props to @0mirka00 for writing this dev notedev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase.. (top)

Components with deprecated margin styles.

Several UIUI User interface components currently ship with styles that give them top and/or bottom margins. This can make it hard to reuse them in arbitrary layouts, where you want different amounts of gap or margin between components.

To better suit modern layout needs, we will gradually deprecate these outer margins. A deprecation will begin with an opt-in period where you can choose to apply the new margin-free styles on a given component instance. Eventually in a future version, the margins will be completely removed.

In WordPress 6.1, the outer margins on the following components have been deprecated.

  • AnglePickerControl
  • FontSizePicker
  • GradientPicker
  • CustomGradientPicker

To start opting into the new margin-free styles, set the __nextHasNoMarginBottom prop to true.

<AnglePickerControl
  value={ angle }
  onChange={ setAngle }
  __nextHasNoMarginBottom={ true }
/>

For more info see #43867, #43436, and #43870.

Props to @0mirka00 for writing this dev note. (top)

Props to @bph and @webcommsat for review of this post.

#6-1, #dev-notes, #dev-notes-6-1

Styling elements in block themes

WordPress 6.1 introduces some new elements to Styles to give 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. theme developers consistent styles across similar elements, and control those in the theme.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. file.

One of the biggest challenges for block themes has been to have consistent styles across similar elements. For example, many blocks display buttons (e.g., Button block, Search block, File block etc.). It has been necessary to include custom CSSCSS Cascading Style Sheets. with the theme to ensure all these button look the same. This CSS approach is no longer necessary in many cases with the 6.1 release.

Prior to the this release, users could style the link and individual heading elements. With 6.1, it is now possible to style the following elements:

  • button
  • caption
  • cite
  • heading

To target these elements in a block theme, simply add them to the theme.json file in your theme:

{
	"styles": {
		"elements" {
			"button": {
				"color": {
					"background": "#000",
					"text": "#fff"
				}
			},
			"caption": {
				"color": {
					"background": "#f00",
					"text": "#00f"
				}
			},
			"cite": {
				"color": {
					"background": "#0f0",
					"text": "f00"
				}
			},
			"heading": {
				"color": {
					"background": "#00f",
					"text": "#0f0"
				}
			}
		}
	}
}

This example only specifies the colors for these elements, but it is possible to specify all the same properties for elements as for blocks.

The heading element will apply to all heading level elements (H1, H2, H3, H4, H5, H6).

Interactive states

Another challenge for block themes has been to control interactive states for elements and blocks, for example changing the color of links when they are hovered. To help with this WordPress 6.1 adds three new “pseudo-selectors” to Styles:

  • :active
  • :focus
  • :hover

These selectors can be applied in theme.json like this:

{
	"styles": {
		"elements": {
			"link": {
				":hover": {
					"color": {
						"text": "#000"
					}
				":active": {
					"color": {
						"text": "#0f0"
					}
				},
				":focus": {
					"color": {
						"text": "#f00"
					}
				}
			}
		}
	}
}

This will result in the following CSS being output in a theme (please note actual output may vary):

a:hover {
    color: #000;
}

a:active {
    color: #0f0;
}

a:focus {
    color: #f00;
}

Again, this example only specifies the colors for these states. It is possible to specify all the same properties for elements as for blocks.

Elements within blocks

This functions similarly at a block level, the only difference being that the rules should be applied to the elements nested within the block you wish to target:

{
    "blocks": {
        "core/group": {
             "elements": {
                "link": {
                    ":hover": {
                        "color": {
                            "text": "red"
                        }
                    }
                }
            }
        }
    }
}

In this case <a> elements within a core/group block will have red text on :hover – this results in the following CSS (actual output may vary):

.wp-block-group a:hover {
    color: red;
}

At the current time support for this feature is intentionally limited to only link (i.e. <a>) and button elements to avoid accessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility) and usability concerns. It may be extended in the future.

Block developers

Another challenge for block themes is integration with third-party blocks. Even if a theme can target all the buttons in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. blocks, there could be any number of third-party blocks that output buttons. It’s not sustainable to expect themes to list all possible button selectors to try to have consistent button styles.

This change provides a solution to this issue, by creating opportunities for block developers to better integrate their blocks with block themes. Now block developers can add the class wp-element-button to any buttons they want to match the theme button styles and the settings from theme.json will be applied. Or wp-element-caption to use for caption, and so on.

Next steps

There are still more elements that can be enabled in Styles to continue improving block themes, particularly form elements like input fields, checkbox, radio buttons and textarea elements. There is a tracking issue for this work.

Documentation: Global Settings & Styles (theme.json)

Props to @get_dave for co-authoring the post, @bph and @webcommsat for review.

#6-1, #dev-notes, #dev-notes-6-1

Performance improvements to the REST API

WordPress 6.1 brings a number of key improvements to the 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/. to increase performance. These improvements decrease the number of database queries that are run on each REST API request. 

Avoid unnecessarily preparing item links

Prior to WordPress 6.1, the prepare_links method in the REST API was called in all controllers. If the _fields parameter is passed to the REST API request, it might mean that the links field is not requested and would never be returned in the response. This is wasteful, as prepare_links can contain database calls or other complex logic that would be run even if it never returned the response. 

In 6.1 prepare_links are only called if requested in the response, when links are requested in fields or the _embedded parameter is passed. As part of this work, the taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. and post type controllers have now been updated to implement said prepare_links method to bring them in line with other REST API controllers. 

This is the code example of implementing this change in custom REST API controllers.

Before

$response = rest_ensure_response( $data );
$links = $this->prepare_links( $post );
$response->add_links( $links );

return $response;

After

$response = rest_ensure_response( $data );

if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
  $links = $this->prepare_links( $post );
  $response->add_links( $links );
}

return $response;

This logic conditionally calls prepare_links only if _links or _embedded is requested. This logic only applies when using the _fields query parameter. When not using _fields, links are included in the response as normal. 

For more info see TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker.: #52992, #56019, #56020

Improvement to the Posts controller

When running profiling tools against the responses of REST API requests, it was discovered that post controllers request a lot of linked data to each post. For example, when returning a post in a REST API response, linked data such as author (user), featured imageFeatured image A featured image is the main image used on your blog archive page and is pulled when the post or page is shared on social media. The image can be used to display in widget areas on your site or in a summary list of posts., and parent post were all requested. As these linked items were not primed in caches, it could mean that for each post in the REST API response there would be 3 separate database queries: one for the user, one for the featured image, and another for the parent post. 

In WordPress 6.1 all the caches are primed in a single database query and there are new helper functions to enable this:

update_post_author_caches

Takes an array of posts and primes users caches in a single query. 

update_post_parent_caches

Takes an array of posts and primes post parents in a single query. 

update_menu_item_cache

Takes an array of posts and primes post / terms link to menu items single query. 

The existing function update_post_thumbnail_cache was used to prime featured image caches. These functions are also being rolled out to other parts of the coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. that can benefit from priming caches in a single place. 

For more info see Trac tickets: #55592, #55593, #55620    

Improvements to other controllers

The comments and user controllers have also been improved: User controller now primes user metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. in a single query and the comments controller now primes the linked post cache in a single query. Improvements were made to the post search controller to improve database performance along with the media controller. 

For more info see Trac tickets: #55674, #56272, #55677, #55716

Props to @flixos90 and @milana_cap for peer review and @mxbclang and @webcommsat for proofreading.

#6-1, #core-restapi, #dev-notes, #dev-notes-6-1, #performance, #rest-api

Block styles generation (Style Engine)

A new 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., known as the “Style Engine”, has been shipped in WordPress 6.1 to provide a single, centralized agent responsible for generating and rendering consistent 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. supports styles on the client-side and server-side.

For the 6.1 release, the focus has been on consolidating how WordPress generates block supports (border, color, spacing, and typography) and layout styles in the editor and frontend.

Before 6.1, a multitude of instances existed where block supports CSSCSS Cascading Style Sheets. and class names were compiled and/or enqueued, both in JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. and PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher, resulting in a great deal of duplication in both code and frontend output. 

It’s imperative to note that the primary and very specific goal of the Style Engine is to improve how the Block editor compiles and renders block CSS, not to provide a universal approach to generating CSS.

Key enhancements in 6.1

WordPress 6.1 introduces a common way to compile, optimize and sanitize block supports styles. Previously block support CSS and class names were generated on demand creating inconsistencies and duplicated code.

Moreover, and one of the biggest improvements, 6.1 brings a way to add styles across the application to a single stylesheet, and also combine repetitive layout-specific CSS rules.

This functionality reduces the number of inline HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. style tags printed to the page: all block supports and layout styles will be rendered to the page as a single, combined stylesheet.

For example, before 6.1, when a page included multiple block layout styles, a CSS rule for each block would be printed in a separate HTML style tagtag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.). The amount of unique style tags for a single page were potentially without limit.

<style>.wp-block-columns.wp-container-1 { flex-wrap: nowrap; }</style>
<style>.wp-block-columns.wp-container-2 { flex-wrap: nowrap; }</style>
<style>.wp-block-columns.wp-container-3 { flex-wrap: nowrap; }</style>

As of 6.1, layout CSS rules with matching CSS definitions are combined in a single HTML style tag:

<style>.wp-block-columns.wp-container-1, .wp-block-columns.wp-container-2, .wp-block-columns.wp-container-3 { flex-wrap: nowrap; }</style>

Public Functions (API)

The following is a general overview of the public functions introduced in 6.1.

Please refer to the API documentation: @wordpress/style-engine for detailed information and example usage.

wp_style_engine_get_styles()

A global public function to generate block styles – CSS and class names – from a style object, e.g. the value of a block’s `attributes.style` object or the top-level styles in theme.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.. Through it, one can store CSS for later retrieval and eventual enqueuing on the frontend.

wp_style_engine_get_stylesheet_from_css_rules()

This function compiles and returns a stylesheet for a set of any CSS rules. Through it, one can store CSS for later retrieval and eventual enqueuing on the frontend.

wp_style_engine_get_stylesheet_from_context()

Returns compiled CSS stylesheet from stored styles, if any have been stored. The style engine will automatically merge declarations and combine selectors. 

JavaScript public functions

The JavaScript API is limited to use within the editor, and compiles only block support styles for now. It ensures that the styles in the editor match those you see on the frontend site. 

compileCSS()

Compiles and returns a CSS stylesheet for a given style object and selector. 

getCSSRules()

Given a style object, it returns a collection of objects containing the selector, if any, the CSS property key (camel case) and the parsed CSS value.

Example usage

WordPress 6.1 primarily uses the public methods cited above to create and enqueue block supports styles from a “style” object usually available as a property on the block attributes

An individual block’s style object may look like this:

$block_styles = array(
     'spacing'    => array(
        'padding' => '10px',
        'margin'  => array(
            'top' => '1em'
            ),
        ),
     'typography' => array(
        'fontSize' => '2.2rem'
    ),
);

wp_style_engine_get_styles() parses and sanitizes the incoming values, then compiles and returns CSS (a compiled string and an array of declarations), which can be used immediately or, if a context is specified in the options, stored for later retrieval.

$styles = wp_style_engine_get_styles(
    $block_styles,
    'options' => array( 'context' => 'block-supports' ),
);

/* 
    $styles is equal to:
    array(
       'css'          => 'padding:10px;margin-top:1em;font-size:2.2rem',
       'declarations' => array( 'padding' => '10px', 'margin-top' => '1em', 'font-size' => '2.2rem' )
    )
*/

Multiple instances of such styles may be “stored” across the application, before the page is rendered, and then retrieved and printed together as a single stylesheet when the page is rendered.

Note: The ‘context’ value is used to group and identify styles, so all styles that belong in the same stylesheet should be stored using the same context value.

The editor could then retrieve the stylesheet for all styles stored under the context value of ‘block-supports’ and enqueue them to be printed to the page in a single style tag:

function enqueue_my_block_supports_styles() {
    $block_supports_stylesheet = wp_style_engine_get_stylesheet_from_context( 'block-supports' );

    if ( ! empty( $block_supports_stylesheet ) ) {
       wp_register_style( 'my-block-supports-stylesheet', false, array(), true, true );
       wp_add_inline_style( 'my-block-supports-stylesheet', $stylesheet );
       wp_enqueue_style( 'my-block-supports-stylesheet' );
    }
}

add_action( 'wp_enqueue_scripts', 'enqueue_my_block_supports_styles' );

Using wp_style_engine_get_stylesheet_from_css_rules() is similar only that, instead of a block styles object, the first argument is a collection of CSS rules from which you can create a stylesheet.

$my_styles = array(
   array(
       'selector'     => '.orange',
       'declarations' => array( 'color' => 'orange' )
   ),
   array(
       'selector'     => '.red',
       'declarations' => array( 'color' => 'red' )
   ),
);

$my_stylesheet = wp_style_engine_get_stylesheet_from_css_rules(
   $my_styles,
   array(
       'context' => 'my-styles',
   )
);

Please refer to the API documentation: @wordpress/style-engine for detailed information and example usage.

Backwards compatibility and best practices

The Style Engine is a new API and, while it replaces the way block supports to generate CSS and class names, it does not modify the functionality of any existing global methods.

While backwards compatibility is a priority, the Style Engine is in its first iteration and therefore the underlying mechanics will be subject to some degree of transformation in the GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and, ultimately, future versions of WordPress. 

To ensure ongoing compatibility, it is recommended to only use the above-mentioned public functions, and avoid calling public methods of any Style Engine utility class.

Current limitations and future enhancements

The Style Engine’s sole function in 6.1 is to generate coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. block supports CSS for the following styles:

  • border
  • color
  • spacing
  • typography

In future iterations, this list may be extensibleExtensible This is the ability to add additional functionality to the code. Plugins extend the WordPress core software..

The next milestones for the Style Engine are:

  • to assume the responsibility of processing and rendering optimized frontend CSS for Global styles
  • providing a way to generate all theme-related styles in one place, and
  • further reducing the footprint of rendered styles

Ongoing development is taking place in WordPress/gutenberg: see the tracking issue and project board.

You can find more context on the history and planned features of the Style Engine on Block editor styles: initiatives and goals.

Further reading

  • Block editor styles: initiatives and goals 
  • GitHubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ tracking issue #38167
  • GitHub project board.
  • API documentation: @wordpress/style-engine

Props: @webcommsat and @bph for review

#6-1, #core-editor, #dev-notes, #dev-notes-6-1, #editor, #gutenberg

Multisite improvements in WordPress 6.1

NOTE: Due to issues reported in #56845, this enhancementenhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. was reverted in r54637 and will not be included in the final 6.1 release. Work will continue in 6.2 and beyond. Please follow along in the original TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. Ticketticket Created for both bug reports and feature development on the bug tracker. (#37181)

Using the metadata 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. for networknetwork (versus site, blog) options

The way that network options are accessed is changing in WordPress 6.1. Network options have always been stored in a meta table called sitemeta. This name is confusing, as “site” in this context means “network,” not to be confused with blogblog (versus network, site) meta, used to store site metadata. Prior to WordPress 6.1, the functions get_network_option, add_network_option, update_network_options, and delete_network_option used custom database queries and caching. This resulted in some performance issues and lots of code to maintain.

In WordPress 6.1, the network options functions have been updated to use the more established metadata API, which is already used for metadata of other object types like posts, terms, and users. This effectively makes a function like get_network_option a wrapper around get_metadata. This has a number of advantages including:

  • Consistency with other metadata types
  • Support for register_meta functionality, such as default values
  • Improved cache priming 
  • Fewer database queries, as all network options are primed in a single request 

Along with these improvements, WP_Network_Query has a new parameter called update_network_meta_cache that allows for all networks in the query to prime the network options in a single query. 

One side effect of this change is that newly updated network options using an integer value may result in a string being returned. When using values like this with an integer comparison, it is important to allow cast to an int. In the old implementation, the second page load of the option would have resulted in returning a string. This change can be considered a fix but it is different from the current behavior. 

This change makes cache group site-options no longer in use and a candidate to be removed in future releases. 

For more information, visit Trac ticket #37181

Store main site ID of network in network options

When a multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site is created in WordPress 6.1, the main site ID on the network is stored in network options. As the main site on the network does not change in most cases, this is a value that can be stored for future reference. This saves a call to WP_Site_Query to look up the main site by domain and path in the bootstrap process which makes This lookup wasteful and not needed. This change also helps setup multiple networks, as noted above, since network options are primed in a single request. This means that when looking up multiple networks, the main site ID is now primed in along with other network options, resulting in fewer database queries / cache lookups. 

For more information, visit Trac ticket #55802

Thanks to @flixos90 and @milana_cap for peer review, and @mxbclang and @webcommsat for proofreading.

#6-1, #core-multisite, #dev-notes, #dev-notes-6-1, #multisite, #performance

Introducing WP_List_Table::get_views_links() in WordPress 6.1

The Problem

Previously, the code to generate markup for views links had to be added in the get_views() method of each child class. This led to repetitive and inconsistent code to achieve the same result, increasing the maintenance burden for CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. and extenders alike.

The Solution

A new method was proposed in ticketticket Created for both bug reports and feature development on the bug tracker. #42066, WP_List_Table::get_views_links(), which abstracts the link generation to the parent class.

This new protected method accepts a $link_data array argument containing the following for each view:

  • $url (string) The link URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org.
  • $label (string) The link label.
  • $current (bool) Optional. Whether this is the currently selected view.

If $current is true, aria-current="page" and class="current" will be added to the item’s link markup.

Usage

  1. In the get_views() method, create an array of link data as documented above.
  2. Pass the array to the new method.
class My_List_Table extends WP_List_Table {
	protected function get_views() {
		// Create link data.
		$base_url  = add_query_arg( 'post_type', 'my_cpt', admin_url( 'edit.php' ) );
		$link_data = array(
			'all' => array(
				'url'     => $base_url,
				'label'   => __( 'All', 'my_textdomain' ),
				'current' => true, // Optional.
			),
			'trash' => array(
				'url'   => add_query_arg( 'post_status', 'trash', $base_url ),
				'label' => __( 'Trash', 'my_text_domain' ),
			),
		);

		// Generate link markup.
		return $this->get_views_links( $link_data );
	}
}

Core Child Class Updates

The following Core child classes now use the new method:

Thanks to @davidbaumwald for peer review.

#6-1, #dev-notes, #dev-notes-6-1

Escaping Table and Field names with wpdb::prepare() in WordPress

This has been postponed from WordPress 6.1. See also Postponed to WP 6.2: Escaping Table and Field names with wpdb::prepare()

As part of WordPress 6.2, wpdb::prepare() has been updated to escape Identifiers (such as Table and Field names) with the %i placeholder (#52506).

This ensures these values are escaped correctly and don’t lead to SQL Injection Vulnerabilities.

Example

$table = 'my_table';
$field = 'my_field';
$value = 'my_value';

$wpdb->prepare('SELECT * FROM %i WHERE %i = %s', $table, $field, $value);

// Output:
//   SELECT * FROM `my_table` WHERE `my_field` = 'my_value'

While this protects you against SQL Injection, where possible you should limit the values the user (attacker) can choose via an allow-list of trusted values; e.g.

$fields = array(
    'name'    => 'user_nicename',
    'url'     => 'user_url',
    'created' => 'DATE(created)',
  );

$sql .= ' ORDER BY ' . ($fields[$order_field] ?? 'user_login');

Performance Improvement

The change to add support for %i has a small performance improvement, as there is a little bit less Regular Expression work involved (generally the more parameters, the better the improvement).

In the Future

This was going to be released in WordPress 6.1, but a problem was identified in RC5 where the use of '%%%s%%' (which can often be seen in LIKE queries) stopped working. For reference, the documentation says “numbered or formatted string placeholders” will not have quotes added by this function (an old/unsafe feature), but this also happens when a placeholder immediately follows a “%”.

WordPress is looking to use %i in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. (#56091).

This change will help developers use the literal-string type for the $query parameter (this is where the $query is written as a developer-defined string, and all user values are provided separately).

Props to @davidbaumwald for reviewing this dev notedev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase..

#6-1, #dev-notes, #dev-notes-6-1, #performance, #wpdb

Create-block scaffolding tool updates

WordPress 6.1 introduces new features and updates to the @wordpress/create-block package used by developer to scaffold new blocks.

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. Variants

The new --variant flag allows users of the tool to choose a block variant to be scaffolded. The internal templates provided by the create-block package support a dynamic and static variant with will scaffold a dynamic and static block respectively. If no variant is passed, the static variant is used.

Scaffolding using the dynamic variant:

npx @wordpress/create-block custom-block --variant=dynamic

Template authors can define variants by adding a variants object to the template definition with each property being the name of a variant and its value an object containing values that can add to or overwrite the default values defined in the defaultValues key. See the create-block-tutorial-template file for an example of defining variants.

Related pull requests: #41289, #43481.

Add additional blocks to an existing pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party

A highly requested feature for the package was to be able to add additional blocks to an existing plugin. With the addition of the --no-plugin flag that is now possible! 

When the command is run with the flag, the tool creates a new set of block files in a subdirectory to the current directory named with the slug passed.

npx @wordpress/create-block custom-block --no-plugin

Related pull requests: #41642.

Enhancements:

  • I18ni18n Internationalization, or the act of writing and preparing code to be fully translatable into other languages. Also see localization. Often written with a lowercase i so it is not confused with a lowercase L or the numeral 1. Often an acquired skill. references have been removed from the internal templates to avoid potential issues with translated strings causing block validation errors ( #43035 )
  • Improvements to the developer experience by prompting to continue the scaffolding process if the tool thinks system requirements are not met ( #42151, #42254 ) and some more general fixes to the scaffold to remove some warnings and errors ( #40479, #41273 ).
  • Adds support for the new render block.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. key ( #44185 )

Documentation

The documentation around creating External Templates has been split into a separate section ( #43718 ) and links to the documentation in the associated create-block-tutorial-template have been fixed to link to the correct places ( #42839 ).

Direct links to all documentation pages for the create-block scaffolding tool:

Props @pbiron, @bph for review

#6-1, #dev-notes, #dev-notes-6-1

Introduction of presets across padding, margin and block gap

WordPress 6.1 introduces preset values for padding, margin and 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. gap. With those the editor implements consistent spacing of blocks and nested blocks out of the box.

The problem

The block editor design tools allowed users only to add custom values for the spacing around block content, eg. padding, margin, or gap.

Dimensions window for padding, margin and block spacing

This means that theme and pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors had no ability to either limit users to a fixed list of spacing options, or to easily change spacing across all of a site’s content if custom spaces have been set on some blocks.

The solution: spacingScale object

theme.json has been extended to include a spacing sizes preset option, similar to the existing font size presets. By default, the editor will generate a range of seven preset sizes that are shared across padding, margin and block gap.

This range is auto-generated from a spacingScale object in the theme.json settings section:

"spacing": {
	"spacingScale": {
		"operator": "*",
		"increment": 1.5,
		"steps": 7,
		"mediumStep": 1.5,
		"unit": "rem"
	}
},

In the above case, the three steps on either side of the medium step of 1.5rem are generated using a multiplier of 1.5, which results in the following array of spacingSizes:

[
  {name: '1', slug: '20', size: '0.44rem'},
  {name: '2', slug: '30', size: '0.67rem'},
  {name: '3', slug: '40', size: '1rem'},
  {name: '4', slug: '50', size: '1.5rem'},
  {name: '5', slug: '60', size: '2.25rem'},
  {name: '6', slug: '70', size: '3.38rem'},
  {name: '7', slug: '80', size: '5.06rem'},
]

It is possible to generate as many steps as needed, and also to use a + operator instead of * to generate these. If a theme has a spacing scale that can’t be auto-generated, then it is possible to include a static array of values in theme.json settings.spacing.spacingSizes.

The spacing sizes are converted to CSSCSS Cascading Style Sheets. properties in the following format:

--wp--preset--spacing--20: 0.44rem;
--wp--preset--spacing--30: 0.67rem;
--wp--preset--spacing--40: 1rem;
--wp--preset--spacing--50: 1.5rem;
--wp--preset--spacing--60: 2.25rem;
--wp--preset--spacing--70: 3.38rem;
--wp--preset--spacing--80: 5.06rem;

Enable fallbacks on Theme switch

There are three reasons for the choice of slugs in the 10,20,30 format:

  1. It is much easier to sort the sizes from smallest to highest, than if the likes of t-shirt sizes were used
  2. For themes that wish to insert additional values between the CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. ones, e.g. a value between Medium and Large, it is easy to do so with a slug of 55
  3. Allow for cross-theme/site compatibility of content if a theme does not support a spacing preset slug in existing content, e.g., a pattern from the pattern library. Numeric values enable a fall back to the nearest match in the current theme. This is also the reason the spacing sizes are generated on either side of Medium. Having a known Medium slug of 50 can hopefully make these fallbacks as accurate as possible.

In the editor UIUI User interface spacing options default to providing the preset option with a toggle to switch back to custom values:

Spacing presets UI

Disable Spacing Presets

  • Disable the spacing presets option by adding the value 0 to settings.spacing.spacingScale.steps in theme.json.
  • Disable the custom spacing sizes by setting settings.spacing.customSpacingSize to false.

Documentation of all theme.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. settings & styles:

How to Guide: Global Settings & Styles (Theme.json)
Theme.json Reference (v2)

Background information

Finalizing the details around these spacing presets has involved a lot of discussion with both theme authors and Core contributorsCore Contributors Core contributors are those who have worked on a release of WordPress, by creating the functions or finding and patching bugs. These contributions are done through Trac. https://core.trac.wordpress.org.. These discussions can be found at the links:

Props to: @glendaviesnz for writing, @webcommsat and @bph for reviewing.

#6-1, #dev-notes, #dev-notes-6-1, #gutenberg

Improved PHP performance for core blocks registration

WordPress 6.1 also comes with a considerable performance improvement for handling blocks in plugins and in the WordPress backend (PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher).

Early block.json Registration Method

Starting with WordPress 5.8, extenders were encouraged to begin to utilize block.json to register blocks through a unified registration process. The benefits offered by this update provide consistency and convenience when registering blocks through PHP or JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/..

However, while this block.json scanning convention is extremely convenient, it does add additional processing when coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. blocks are instantiated. On each page load, 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. registration undergoes the following steps:

  • Scan folders for block.json files.
  • When a block.json file is found, read its contents into memory.
  • Call json_decode on the file contents to convert it to a PHP array.
  • Register the block using the decoded data.

With over 70 core block files to scan and load, this presented an opportunity for optimization.

Core Block Registration Update

To reduce filesystem reads and processing of block.json files, which should benefit all WordPress sites and improve performance, block registration has been updated to:

  • Introduce a new Grunt task (copy:block-json) that scans and converts core block.json files to PHP arrays and stores them in a single blocks-json.php at build time.
  • Use the new blocks-json.php file in the register_block_type_from_metadata() function.
  • Assign the block registration data to a static variable (cache) so that it’s only loaded once per request.

The addition of an extra build task to compile the decoded 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. data to PHP reduces block registration filesystem reads from ~70 files to just a single file. And since blocks-json.php is a native PHP array, it can be used directly without additional conversion.

The conversion from block.json files to PHP arrays is achieved through the json2php package, which is already utilized in Core and GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/.

References

Props to @aristath for source material and collaboration, and to @milana_cap for review of this dev notedev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase..

#6-1, #dev-notes, #dev-notes-6-1, #performance