Options API: Disabling autoload for large options

Authors: @pbearne and @joemcgill

WordPress automatically loads multiple options with a single query on each page request in order to be more efficient—a technique called “autoloading”. Prior to [57920], developers could control whether their option should be autoloaded by passing either "yes"/true or "no"/false to the third parameter of add_option() or update_option(). However, the decision to make that parameter optional, with a default value of "yes" has led to many options being loaded on every page unnecessarily (see #42441). 

Autoloading a large amount of data that is not used negatively impacts website performance, particularly when an option containing a large amount of data is not used.

[57920] introduces several changes to the Options 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. to optimize autoloading behavior.

Changes to the options API

To support this optimization for autoloading behavior, and to create a way to apply further optimizations going forward, the following changes to the Options API have been made.

New default $autoload value

The default value for the $autoload parameter of add_option() and update_option() is being changed from "yes" to  null, to allow WordPress to differentiate between an option with an autoload value that is explicitly set, and one where it can dynamically determine whether an option should be autoloaded. As a result, there are now three recommended values for the autoload parameter:

  • true: always autoload; Use this when an option should load on every page to avoid an additional DB query.
  • false:  never autoload; Use this when an option is rarely used to avoid wasted data being loaded on every page.
  • null: maybe autoload; Allow the autoload value to be dynamically determined. By default, WordPress will still autoload options using the default value unless they contain large values (described below).

For backwards compatibility, the previous values of "yes" and "no" are still supported and mapped to true and false, respectively.

Updated database autoload values

Previously, all options were stored in the database with an autoload value of either “yes” or “no”. Starting with this change, the autoload value for newly updated options will now be one of the following values:

  • on’: Added with an explicit true value and MUST be autoloaded (needed on EVERY page).
  • off:‘ Added with an explicit false value and MUST not be autoloaded (e.g. only used on a single adminadmin (and super admin) page) .
  • auto’: Added without an explicit value and will rely on WP default autoloading behavior. In WordPress 6.6 these SHOULD autoload, but the default may change in the future.
  • auto-on’: Added with a dynamically set to true value and SHOULD be autoloaded.
  • auto-off’: Added with a dynamically set to false value and SHOULD NOT be autoloaded.

No upgrade routine is planned for this change, so previously added options will still be stored with “yes” or “no” values, which will be treated like “on” and “off”, respectively. If you have implemented any custom SQL to read or write autoload values, you should update them to use the new values.

Newly introduced public functions and filters

Several new functions and filters are available to make working with the new autoload values easier.

New Function

  • wp_autoload_values_to_autoload() – Returns all database values that should be autoloaded. Defaults to an array containing 'yes', 'on', 'auto-on', and 'auto'.

New Filters

  • wp_autoload_values_to_autoload – Edit the list of autoload values stored in the database values that should be autoloaded. At this time, the filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. only allows values to be removed.
  • wp_default_autoload_value – Determine the default autoload value for an option where no explicit value is passed. Return a boolean false value to disable autoloading.
  • wp_max_autoloaded_option_sizeModify the size threshold above which options will not be autoloaded by default. Defaults to 150000, i.e., 150k bytes.

Disabling autoload for large options

To address the issue of autoloading excessively large options, when an option is added via add_option() or an option’s value is changed via update_option(), WordPress will now dynamically disable the autoload behavior by checking the size of the value before updating the database. For any options that do not explicitly pass true to the $autoload parameter, a value that is greater than 150k bytes will no longer be set to autoload.

Preparing for this update

To prepare for this update, developers should update calls to add_option() and update_option() in their code to explicitly set an autoload value using the new preferred true or false values in order to control the autoload behavior for your options. Otherwise, continue using the default value to allow for autoload optimizations to be dynamically applied.

Ensuring a large option is still autoloaded

If you need to ensure a specific large option is autoloaded after this change and cannot directly change the code where that option is saved, you can make use of the new wp_default_autoload_value filter.

Note: Do this with care, and only for options that are needed on every page.

add_filter( 'wp_default_autoload_value', 'my_large_value_autoload', 10, 2 );

function my_large_value_autoload( $autoload, $option ) {
    if ( 'my-large-option' === $option ) {
        return true;
    }
    
    return $autoload;
}

Adjusting the threshold for large options

If you want to change the size threshold for when options should no longer be autoloaded, you can use the new wp_max_autoloaded_option_size filter. Increasing this value is not recommended, as it could lead to slower performance.

add_filter( 'wp_max_autoloaded_option_size', 'my_max_autoload_option_size' );

function my_max_autoload_option_size( $size ) {
    // Reduce the threshold for large sizes to 100K (Default is 150K).
    return 100000;
}

Auditing your site for large options

WordPress 6.6 will include a new Site Health check, which will display a critical issue that says “Autoloaded options could affect performance” if the total size of your autoloaded options exceeds 800 KB.

To audit your site for large options that are currently being autoloaded, you can run an enhanced version of this same Site Health check by installing the Performance Lab plugin from the WordPress Performance Team. Once activated, the 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 will add additional information to the Site Health check so you can review and disable any options that do not need to be autoloaded in the Site Health check.

Screenshot of the advanced table shown by the Performance Lab plugin

Other changes to the Options API in WordPress 6.6

  • Introduce wp_prime_network_option_caches() to load multiple networknetwork (versus site, blog) options with a single database request (#61053)
  • Prime transient and transient timeout options in the transient and site transient APIs (#61193, #61053)
  • Update default autoload values used in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. (#61045)
  • Add 'label' argument to register_setting() (#61023)

Props to @flixos90, @peterwilsoncc,@adamsilverstein, @mukesh27 and @desrosj for contributing to and reviewing this post.

#dev-notes

Developer Blog editorial meeting summary, 6 June, 2024

Summary of the WordPress Developer Blogblog (versus network, site) meeting, which took place in the  #core-dev-blog channel on the Make WordPress SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/.. Start of the meeting in Slack.

Attendees: @greenshady, @ndiego, @webcommsat, @psykro, @colorful-tones, @milana_cap, @mobarak, @magdalenapaciorek, @juanmaguitar, @bph (as facilitator). @ironnysh and @bcworkz (async)

Last meeting notes: Developer Blog editorial meeting summary, May 2, 2024

Updates on the site

The site has passed the first 1,000 subscribers :rocket: Don’t want to miss the next blog post? Subscribe. And please share the links with your networknetwork (versus site, blog) as well. @webcommsat volunteered to submit an amplification request to the WordPress marketing team to celebrate the milestone with the community.

Newly published post since the last meeting: 

Since the last meeting, we published four articles.

Huge Thank you to the writer and reviewers! 

Project Status

The project board for Developer Blog content is on 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/.

In review

In Progress:

Post on the To-do-list, assigned to writers.

Topics, approved, in need of a writer

If you are interested in taking on a topic from this list or know someone who would be a good person to write about them, comment on the Issue or pingPing The act of sending a very small amount of data to an end point. Ping is used in computer science to illicit a response from a target server to test it’s connection. Ping is also a term used by Slack users to @ someone or send them a direct message (DM). Users might say something along the lines of “Ping me when the meeting starts.” @bph in slack either in the #core-dev-blog channel or in a DM.

New Topics approved

Topic not approved:

The WordPress Developer Survey – A regular survey could give “the whole project a lot of useful data” There were concerns about logistical challenges and needs further discussion with coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., the marketing team in its new media focus, and with Learn WP. The next step as identified as “to define the purpose of the survey, and what questions would be included/not included.” The discussion continues on GitHub

Open Floor

@webcommsat Inquired about topics schedule around the WordPress 6.6 release. There are a few posts already on the list or were just approved. As almost all topics are assigned to writers. Contributor’s bandwidth will determine the publishing timeline.

@colorful-tones requested input and possible resources on using Playground for his upcoming post on the developer Blog: a Good starting point is the Blueprint Gallery and an example from @greenshady on GitHub.

@colorful-tones has slightly changed the topic of his post he has been working on. It was originally thought to be an Interactivity 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. tutorial, but as you can read in the issue he went a different route. It was concluded that “it’s still a valuable post for the Dev Blog”, “the new focus is still really useful” and “the underlying method doesn’t need to be the same as the originally proposed method”

Next meeting: July 4, 2024, at 13:00 UTC in the #core-dev-blog channel

Props to @greenshady for review of the post.

#meeting, #meta, #summary

Proposal: Bits as dynamic tokens.

A proposal for starting to introduce Bits (dynamic tokens/placeholders) into WordPress.

When Blocks came into the scene Shortcodes were largely abandoned, but Shortcodes had value. They had many problems, but they also had value. It wasn’t clear at the time how to bring them back without bringing back many of the problems they brought with them, namely issues surrounding ambiguity in parsing, nesting, changing the page in dramatic ways, and providing usable content in the absence of a required 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 or theme.

Around two years ago a discussion was started for introducing dynamic tokens in the editor as placeholders for externally-sourced content. The idea was raised before the discussion was started: many developers were starting to introduce unique code in multiple blocks and plugins that looked for ways to find and replace content in the editor:

  • Set an image URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org to the post’s 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..
  • Insert a placeholder for a subscriber’s name in an email form.
  • Add the post author’s display name in a query loopLoop The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. template.
  • Write a translatable string in a theme template inside the Site Editor.

When the HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. 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. started developing it changed the game for these kinds of dynamic tokens. Previously the discussion was largely blocked by finding a syntax that would be reasonable for someone to type in directly, but also avoid causing all sorts of breakage to the surrounding HTML. Now, these discussions are less relevant because the HTML API provides a way to find various kinds of placeholders and then ensure a context-aware replacement and escaping when replacing them.

It provides a way for WordPress to make heuristics-based decisions on what content to allow and not to allow on output. It ensures that the output of one of the tokens doesn’t bleed into or break the page around it.

After many explorations, one form of placeholders stands out above all the others – a quirk in the HTML specification referred to within WordPress as a “funky comment.” These look like closing tags, except the 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.) name is invalidinvalid A resolution on the bug tracker (and generally common in software development, sometimes also notabug) that indicates the ticket is not a bug, is a support request, or is generally invalid.. When a browser sees them they interpret them as HTML comments, removing them by default from the page (in the case that the server fails to replace them), and it’s impossible to nest them.

These funky comments are the perfect vehicle for safe fallback, human-typability, and the ability to parse and replace. While funky comments can appear in many forms, this proposal is discussing the specific form that can be used for dynamic tokens and placeholders: these are called Bits. While blocks represent rich content types, Bits represent small semantic bits of knowledge. Bits can appear in any 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. or in any HTML without requiring any changes to any existing Block code; Bits can appear anywhere.

What is a Bit?

<//wp:post-meta key="isbn">

A Bit is a small token of semantic meaning. It references content sourced beyond the post or content in which it’s found. It could refer to metadata about a post, a post 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. field, a stock price sourced from an API call, a countdown to a particular date, the local time of a given timestamp in the reader’s timezone, a plugin URL, a view counter, a render for a math formula, or any other bit of knowledge that is provided by the server when rendering a post.

Bits are a form of horizontal composition. Blocks don’t need to know about Bits for someone to use Bits. Bits are a form of user control: anyone can add a Bit into their post without needing a developer to adjust their Blocks or theme first.

Bits are like blocks in that they comprise a name and a set of attributes, but unlike Blocks, Bits cannot nest. They are the inline analogue to block-oriented Blocks. Bits can provide some HTML, but not much. Bits are configurable by their attributes: a post date can be configured to display as “May 22” or “2010/05/22.”

Bits are registered both in PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher and also inside the editor. There’s an inspector panel for configuring a Bit based on the registration with semantic-specific controls, but Bits can also be manually typed from the visual view of the editor, and it will recognize them once typed.

Bits can be found in various contents, including plaintext and markup contexts. Bit implementations must provide both of these outputs, as well as a fallback so that they can provide some meaningful value when the necessary rendering code is missing. For example, a Bit providing a URL will might URL-encode it for URL attributes, but leave non-ASCII unicode characters in place for display purposes; a post date might return a standardized string timestamp for plaintext context but a <span>-annotated human-readable date for better CSSCSS Cascading Style Sheets. styling in markup contexts.

<!-- stored in a post -->
<time datetime="<//wp-bit:post-date format='RFC9557'>"><//wp-bit:post-date format="human-diff"></time>

<!-- rendered to the reader -->
<time datetime="2024-05-22T12:00:00+00:00">eighteen days ago</time>

Bits are parsed just like any other HTML closing tag except: the “tag name” cannot start with a-z; they extend from the start of the “tag name” until the very first > (even if it’s inside a quoted value). The attributes are parsed just like HTML attributes, meaning that there can be unquoted, single-quoted, and double-quoted attributes. The only caveat is that when found inside an HTML attribute, the quoting cannot conflictconflict A conflict occurs when a patch changes code that was modified after the patch was created. These patches are considered stale, and will require a refresh of the changes before it can be applied, or the conflicts will need to be resolved..

How do humans interact with Bits?

The editor has two inherent view modes for Bits: a preview mode, and a token mode. The Preview mode may show a preview of the replaced value of the Bit where it’s found, and it may indicate that the Bit is there through some visual indication or otherwise. The token mode shows the Bits as placeholders indicating which kind of Bit they are.

An example of how a bit might look in token mode in the editor, clearly showing the type and configuration.
An early exploration of an ISBN post-meta bit from @ellatrix, in the editor’s preview mode.

Bits are designed so that someone who is used to working with them can enter them directly as text, but people won’t need to know anything about their syntax in order to use them. Bit registration in the editor provides a name, a description, and some additional metadata just like Blocks to make it possible to provide a discoverable system for finding and configuring them.

The Bits inserter appears when typing //. Whereas the slash inserter shows Blocks on a single /, if someone types a second, they will instead see a list of Bits that will auto-filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. as they continue to type. The // for the slash inserter corresponds to the Bit syntax <//wp-bit:core/hello-dolly>.

Bit registration in the editor also provides an optional configuration panel akin to Block Inspector controls. Since each Bit carries its own semantics, these controls guide authors into how to configure Bit, maybe by selecting formatting options, choosing an associated post ID (by searching for its title), or choosing which of several options to enable.

What about Block Bindings?

Bits and Block Bindings are related but complementary systems. While Block Bindings can be thought of primarily as a developer-oriented API, where a developer can open up a given block or a subset of a block’s attributes to be replaced by some other source of data, Bits are primarily author-oriented, giving end-users the ability to add sourced content anywhere.

There is likely a large overlap in the kinds of data sources that power each system. Ideally, the registered sources will be compatible with both.

Proposal

The HTML API already introduced the concept of a “funky comment,” which is the tag closer with an invalid tag name. For WordPress 6.6 this document is only proposing to unlock storing the funky comments in CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. so that 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/ the plugin can experiment with various prototypes of the Bit system with its full lifecycle. Currently this requires combining a Gutenberg patchpatch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing. and a Core patch.

The only thing required for WordPress 6.6 is a big-fix to existing code, which would be useful even if Bits don’t come to be, and even if they use a different syntax: WordPress attempts to separate HTML comments from other tags, but it’s unaware of the myriad ways that invalid HTML turns into comments. Core-61009 introduces a patch that makes Core more aware of a couple new types of syntax-turned comments.

By opening up the ability to store Bits in the database, it makes it easier to start exploring Bits as a broader system, including what ought to be built an how. Until then, it remains cumbersome. Even in the case that Bits use a different syntax, this patch is still improves WordPress’ understanding of HTML.


With the ability to store Bits in the database, work should progress rapidly during the WordPress 6.7 development cycle, building up editor flows to discover, configure, and render Bits. Work will be explored in Core for registering them on the backend, and it will likely work together with a system for HTML templating powered by the HTML API.


For future releases and design, your feedback is invited in defining the interfaces for registering, displaying, interacting with, and governing Bits.

Acknowledgements

Thanks to @annezazu, @antonvlasenko, @ironprogrammer, @ellatrix, and @gziolo (and anyone else I forgot) for review and feedback on this post before publishing.

Data Views Update – June 2024

With the last few releases of WordPress, the glimmers of phase 3 of 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/ roadmap are starting to shine through, namely in the form of the new powerful Data Views. While exciting to see a glimpse of what’s to come, it’s also causing an understandable increase in questions – What can we use today? What should we use based on each use case? What work is coming up next? This post seeks to provide answers at a high level view of these questions, along with some general context as to what’s being done and why. It’s pulled from a wide range of conversations including advancing the site editor index views, Roadmap to 6.6, and more. This is and shall continue to be an evolving conversation.

Background: 

What problems are Data Views trying to solve?

The current WP List Tables lack the flexibility required for more complex websites and are not suited for the technological demands of phase 3, which emphasizes collaboration workflows like saving and sharing specific views. Data Views aims to revolutionize these views by providing enhanced functionality, including alternative display options, extensive customization capabilities, and robust extension points.

What are Data Views? 

Data Views refers to an improved and reusable UIUI User interface for different screens in WordPress that deal with collections of things whether that’s templates, patterns, posts, media, and more. Currently, those views are known as WP List Tables and Data Views seeks to replace those over time. It’s being built with extensibility in mind and is a big part of phase 3, specifically the Adminadmin (and super admin) Redesign efforts. This new UI will also power other long term future parts of phase 3 work, including workflow improvements for assigning folks to review posts or creating custom views to streamline processes. Currently, the Data Views are isolated just to the Site Editor and an initial version was released in 6.5 with a broader iteration underway for 6.6.

Below is a video showing the current WP List Tables in comparison to the new Data Views, showing both shared functionality and some of what the Data Views can offer that WP List Tables can’t, like different layouts, exposing more fields, and offering previews:

Why is the work being approached this way?

This work is intentionally being done first in the Site Editor with private APIs to allow for quick iteration and a more narrow impact than starting in the broader wp-admin landscape. The following principles are in mind as this work is underway:

  • Iteratively, with each step bringing meaningful improvements.
  • Stay subject to feedback from the broader community.
  • Stay backwards compatible.
  • Focus on 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).
  • Built with extensibility in mind from the start. 
  • Best in class user experience. 

Ultimately, whatever is shipped publicly will need to be maintained and it’s important to avoid disruptive changes while these efforts are in an iterative stage.  

What’s happening for WordPress 6.6?

For WordPress 6.6, set to launch in July, the release includes work to bring the various management pages forward in the Site Editor (manage all templates, manage all template parts, manage all pages) so those options are immediately seen when visiting the respective sections, reducing the number of steps to access important information. For pages, a new side by side layout will be introduced so one can see both a list of all pages and a preview of the currently selected page. For patterns, template part management will be removed and integrated into the current overall patterns section. Interspersed within all of these larger changes are smaller enhancements in functionality and feel, including details normalization that will eventually scale up into a bulk editing tool.

What’s coming up after WordPress 6.6?

A major priority is extensibility APIs so plugins in the future can begin altering and extending these pages, inevitably resulting in more feedback. Currently, an initial API has been bootstrapped to allow third-party developers to register and unregister post type actions with broader, high level plans outlined.

Outside of that, there are explorations underway to bring the new list views, as an opt-in experiment in the 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, to the Posts listing and the Media library. These are intentionally being done as experiments for now to see what might be viable for a future release and will take the form of contained Site Editor-like instances. At the same time, a Data Views Forms effort is underway that’s meant to allow for bulk editing first and, in the future, to be a framework to generate forms and details panels.

Re-imagined WordPress Media Library showing an organized sidebar with categories, file types, and tags on the left with a list of all media files in the frame.

A design that imagines a Data Views powered Media Library experience

Can we use Data Views?

TLDR: This work is in an evolving middle stage where feedback is needed but what’s being done isn’t fully formed to implement wholesale. 

Extensibility has been a key piece of this work baked into all of these efforts from the very beginning. However, in order to move quickly to build on new parts of Data Views and avoid breaking changes, these APIs are currently Gutenberg plugin-only APIs. At the same time, it’s important to get extender feedback to shape the work being done. 

For now, folks can bundle the Data Views styles into a plugin. You can even copy/paste these frames in the design library for quick mockups. Currently, the @wordpress/dataviews package is public already, meaning you can install it, use it from npm, and bundle it in your own scripts. What remains private is that it’s not exposed as a WP global, which means future breaking changes are possible but you’ll be able to upgrade the package at your own pace if you bundle it. There are also no extensibility APIs for the CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. provided data-views yet for WordPress 6.6 (Templates, pages, patterns) which means you can’t alter these pages yet from a WordPress plugin. As mentioned above, an initial API has been bootstrapped to allow third-party developers to register and unregister post type actions with broader, high level plans outlined for furthering extensibility. 

For those who can adopt this work, please do and report back around the edges you find so we can iterate. For some, you may need to wait until it’s fully formed. The answer depends on what you’re trying to do and on what timescale. As always though, going as native as possible as soon as possible is beneficial both to ensure what’s being built works for your use case and to prevent the future work that will be needed to adopt what’s built. 

In the future, you can imagine a more customizable interface all within the same current navigation structure rather than a wp-admin like interface. Folks can pick and choose which plugin interfaces to pin and use, rearrange navigation items, and experience a similar flow and presentation no matter where they go. We aren’t there yet but we’re on a path in that direction:

View of an imagined WordPress interface with a sidebar showing various options to select between and a preview of the site in question.

Where can I follow along and provide feedback?

Feedback is wanted and needed! Here are a few ways to follow along, depending on the level you want:

To share feedback and ask questions, check currently open issues to leave a comment or open a new GitHub issue in the Gutenberg repo. This post is simply to share an update and the best place to get involved in a discussion is in 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/. If you have clarifying questions about the post itself, you’re welcome to ask them.

Thank you to @fabiankaegy @jorbin @youknowriad @joemcgill @mikachan for reviewing and collaborating on this post. Thank you to @joen for creating the video used.

#gutenberg, #phase-3, #plugins

Summary of Hallway Hangout on what’s next in Gutenberg

This is a summary of a Hallway Hangout that was first announced on Make Core. The aim was to have a shared space where we could chat about what’s being worked on to provide broader awareness to more WordPress contributors and get feedback. The hope is that by coming together early before the next betaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. period to talk about different features, we can, as a community, flush out concerns sooner, help more folks get involved, and find ways to work better together. Thank you to the 18 folks who joined and to @saxonafletcher and @richtabor for demoing. 

Video Recording:

Demos:

The first hour or so covered demos of features with a few questions mixed throughout. What follows is a high level description of the demo topic with links to 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/ issues to dive into more and questions asked and answered related to the topic. To make it easier to follow, I also tried my best to split each demo into each section so folks can pick and choose to engage as they’d like. This doesn’t include the full footage but it includes the relevant bits for demoing.

Theme Style Presets

Rich quickly went through at a high level theme style variations, using Twenty Twenty-Four theme as a use case. He then went through abstracting color and typography styles (more than just fonts and includes things like letter spacing) as their own presets. This work was initially merged in a recent PR and works with all existing themes today that support style variations. Going forward, there are some technical details to iron out along with potentially evolving the experience to better support themes with a large set of variations. For a greater view of this general area, dive into the Colors and typeset presets from theme style variations overview issue

Section Styles

Rich recapped the 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. style variations mechanism and how you can register variations via 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. for multiple blocks at a time, including a demo of how this functionality would work in the editor to allow for “section styles”. This isn’t inventing anything new but modifying existing functionality of block styles. The biggest new functionality is that you can assign a variation to multiple blocks and to child blocks at one time. For Rich’s demo, switching between variations changed the styling for Group, Column, and Columns blocks. Overall, this work for 6.6 is being tracked here with the biggest PR still underway to extend block style variations as a mechanism to support this.

Q: For light/dark in the block styles demo, how are these configured differently than a block style or block variation?

Reusing block style variation and applying it to all child/nested blocks too. With all of those combinations, can still granularly change things. It’s make theme.json more portable across themes. 

Q: Are there any naming conventions needed for consistency of colors?

Any theme can decide what these variations look like so it doesn’t matter what the color slugs are that a theme uses. In previous themes, base and contrast were primary color slugs used but any other color combinations you can’t guarantee. This allows the theme to define what combinations of colors work well and the theme styles that variation rather than guessing and match up different slugs. 

We briefly touched on the many related issues there are around color naming as a broader topic: #29568 & #53996 & 39372.

Q: Is the theme.json you are showing available to look at somewhere?

Yes. Here’s the relevant, new bits from Rich’s demo:

{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 2,
"title": "Section Styles",
"styles": {
"blocks": {
"variations": {
"colorway-1": {
"supportedBlockTypes": [
"core/group",
"core/columns"
],
"color": {
"background": "var(--wp--preset--color--theme-2)",
"text": "var(--wp--preset--color--theme-3)"
},
"blocks": {
"core/separator": {
"color": {
"text": "var(--wp--preset--color--theme-3)"
}
},
"core/heading": {
"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--theme-3)"
}
}
}
}
},
"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--theme-3)"
}
},
"button": {
"color": {
"background": "var(--wp--preset--color--theme-3)",
"text": "var(--wp--preset--color--theme-1)"
},
":hover": {
"color": {
"background": "var(--wp--preset--color--theme-4)",
"text": "var(--wp--preset--color--theme-1)"
}
}
},
"heading": {
"color": {
"text": "var(--wp--preset--color--theme-3)"
}
}
}
},
"colorway-2": {
"supportedBlockTypes": [
"core/group",
"core/columns"
],
"color": {
"background": "var(--wp--preset--color--theme-4)",
"text": "var(--wp--preset--color--theme-2)"
},
"blocks": {
"core/separator": {
"color": {
"text": "var(--wp--preset--color--theme-2)"
}
},
"core/heading": {
"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--theme-1)"
}
}
}
}
},
"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--theme-2)"
}
},
"caption": {
"color": {
"text": "var(--wp--preset--color--theme-2)"
}
},
"button": {
"color": {
"background": "var(--wp--preset--color--theme-1)",
"text": "var(--wp--preset--color--theme-4)"
},
":hover": {
"color": {
"background": "#FFFFFFE3",
"text": "var(--wp--preset--color--theme-4)"
}
}
},
"heading": {
"color": {
"text": "var(--wp--preset--color--theme-1)"
}
}
}
},
"colorway-3": {
"supportedBlockTypes": [
"core/group",
"core/columns"
],
"color": {
"background": "var(--wp--preset--color--theme-5)",
"text": "var(--wp--preset--color--theme-2)"
},
"blocks": {
"core/separator": {
"color": {
"text": "var(--wp--preset--color--theme-1)"
}
},
"core/heading": {
"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--theme-1)"
}
}
}
}
},
"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--theme-2)"
}
},
"caption": {
"color": {
"text": "var(--wp--preset--color--theme-2)"
}
},
"button": {
"color": {
"background": "var(--wp--preset--color--theme-3)",
"text": "var(--wp--preset--color--theme-1)"
},
":hover": {
"color": {
"background": "var(--wp--preset--color--theme-4)",
"text": "var(--wp--preset--color--theme-1)"
}
}
},
"heading": {
"color": {
"text": "var(--wp--preset--color--theme-1)"
}
}
}
}
}
}
}
}

Q: Are these essentially class-based? i.e. will these style variations still work with CSSCSS Cascading Style Sheets. files (and JSON at the same time)?

Yes, class based like other block style variations.

Zoomed out view

Rich demoed the work being done around zoomed out editing which emphasizes patterns rather than editing blocks, allowing you to quickly build with patterns (reorder, delete, apply section styles, shuffle). There are some UXUX User experience considerations to figure out, including ensuring the mode is invoked at the right time and drag & drop works well. The work done here could also apply in the future to the experience of adding a new page or even onboarding into WordPress. It’s unclear right now whether it’s something that will be a toggle to use as you want or a view that’s offered in targeted moments (ie global styles or inserting patterns). 

Q: By zooming out for the pattern view – does that mean that patterns aren’t still useful for smaller groups of blocks (i.e. wanting to add a CTA pattern to a column)?

These patterns are still useful! This new option is simply offering a different context and allowing you to engage with patterns in a different way. This is also something to figure out how to do to provide a level to add patterns to a specific section. 

Q: I’m missing the purpose of the shuffle button. What if it was a button the showed all relevant patterns to replace the current one with?

It’s an exploration to see if it’s viable and it might not be where we end up. Of note, shuffling just goes to the next pattern rather than a random pattern. We talked at this point about different ways of interacting with patterns, including replacing patterns in the Inspector or selecting patterns from a modal (query loopLoop The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. block) or shuffling. 

Advancing data views

Saxon demoed the latest work around Data Views including a new list view layout type for posts, new default views for templates, and the efforts done to merge patterns & template parts. He discussed being able to set custom views and how useful that will be especially in an enterprise context when lots of folks are working across content. He also shared a figma prototype showing what it might look like with products, rather than posts/pages, to show a custom post typeCustom Post Type WordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. experience. 

As part of this broader work, the Details and Inspector are being unified to simplify both where to find information and the steps to get to editing (without the Details panel, you can go straight into the editing experience). We discussed extensibility, namely around the APIs currently being private but how the work is being tackled with extensibility at its coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.. For folks who want to explore today, they can bundle the data view styles in their plugin. In looking ahead, we also talked about responsiveness improvements and how consumers of these components can decide how to define the experience, including any default views or custom views. 

Q: That preview of the “product custom fields” as a screen you see before the editor – how does that design relate to the modal for legacy metaboxes that is also happening?

Ideally any data values associated with a post type should be actionable within data views, including generating fields for data. Currently, the data views work is looking at ways to quick edit and bulk edit when selecting multiple items. In some cases, this might be done by editing in the Inspector. There needs to be a broader discussion to define what’s shown in each view vs in the inspector instead of at the bottom. In some cases, there are benefits for things that require more space, like products, to having a more detail style view as a middle step, to allow for editing rather than having something on the bottom or side where you’re trying to edit something in a smaller space. 

As part of this answer, we also talked about the upcoming developer hours on alternatives to custom metaboxes. 

Q: Are we able to control where our custom post type appears in the sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. order?

Not yet! Need to figure out more technical details, including around routing

Overrides in synced patterns

Saxon went through what synced patterns are along with how overrides function, allowing you to edit a part of a synced pattern while keeping the rest in sync, and showcased a synced pattern with overrides and contentOnly editing enabled. This work is being tracked for 6.6 after being punted from 6.5. As part of this overall feature, we also discussed advancing contentOnly editing to create a simpler editing experience by surfacing more top level sections rather than needing to work about the block hierarchy and providing easy access to edit specific aspects in the inspector. 

Q: Would like to hear thoughts on pattern overrides/content locking working with blocks that use repeatable inner blocks (lists, buttons, etc)? 

This touches on a common limitation of these kinds of tools and is captured in a related GitHub issue. We talked about how, in the future, you can add overrides for all inner blocks as a way to work around this but, for now, this limitation remains. For example, you could make a grid block overrideable with all children within it inheriting the same.

Block connections

Saxon demoed block connections with an example post type called “Events” with a custom template with a handful of blocks connected to custom fields (location, venue). Right now, this connection has to be made in code including for what’s planned for 6.6 but there’s a larger vision that includes how this could be edited in the interface in the future. For 6.6 though, the ability to edit the custom fieldCustom Field Custom Field, also referred to as post meta, is a feature in WordPress. It allows users to add additional information when writing a post, eg contributors’ names, auth. WordPress stores this information as metadata. Users can display this meta data by using template tags in their WordPress themes. visually is planned. Saxon demoed this by editing the custom field directly in an individual event post and showing how it was updated in the posts lists automatically. Saxon also showed how the data will all remain in sync if you have the custom field displayed in multiple places. As a final demo, Saxon showed a Query Loop block querying through the events post type and how he can simply copy/paste the blocks with custom fields into the Query Loop to reuse the functionality there. 

Q: Do these fields have to be registered somewhere or are they automatically detected/available by adding it via the code editor?

Yes, they need to be registered and be “non-protected”. Here’s part 1 and part 2 of a developer blogblog (versus network, site) post on connecting custom fields for more information.  

Q: What field types (text, select, relationship) is this expected to support when introduced? For custom fields and block binding. 

For 6.5, the following are supported: 

  • Paragraph: content.
  • Heading: content.
  • Image: URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org, alt, and title.
  • Button: text, URL, linkTarget, rel.

Grid layout

Saxon showed the work in progress layout improvements for the Grid layout option. There are two modes in Grid: auto (set minimum column width and can’t manually set items) and manual (set number of columns, set number of rows, and manually set items). Once a grid is placed in manual mode, you can reposition them and create new items. Saxon discussed the explorations around being able to “pin to grid” as a way to say that a grid item should never move and how with manual mode this idea of pinning would go away leaving everything to be seen as pinned to the grid manually. This makes manual mode more complex and, for something more structured, that’s where auto mode would be used. A big part of the entire feature is figuring out the best default experience for folks. If you want to follow this work, there’s now a slackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel for discussions: #feature-grid

Q: Any thoughts on how some of these more unique grid layouts will work on mobile?

There are lots of various discussions around how best to do this and we need to be smart initially around how to stack items, like stack on mobile for columns.

Q: Can we overlap items?

Not yet. There’s a limit in place to prevent that. You can create overlapping items but for v1 we will limit how you can do that. The end goal is you can in the future.

Additional questions

Q: Summarizing a question asked live –  where do I get new information about what’s coming up, especially outside of the technical resources? What do I have to follow? 

We talked about how all levels of communication are needed from longer tutorials to quick reels to user friendly resources to deeply technical walkthroughs. This is a “forever problem” that cuts across how information is found on the WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ website to release resources to the entire experience of using WordPress. We talked about how the media corps work might help with this too. 

Q: How do we feel about the fact that the Fonts 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. exist while also encouraging theme builders to ship fonts so that variations (typography) are available in global styles? Themes are sometimes shipping 50 fonts. How much do we ship? Should a theme ship with no font? A lot of these themes are huge! This is a more philosophical question. 

We talked about how we could potentially reconcile these so declaring a font family in theme.json could potentially bring it into the site editor but that, in general, fonts should still provide presets for users. Ideally, it can all be connected to the font library to keep fonts in one place but we shouldn’t make users go hunting for fonts and themes should be opinionated in how they want folks to use it. 

Q: I’d love to hear if anyone has a fix for this issue I’m dealing with regarding caching and style variations.  tldr the style variations cache doesn’t clear, so you have to switch back and forth between variations to clear it while working on a new theme.

Please chime in on the issue if you think you can help! None of us on the call had a good answer for it as it mainly requires a workaround rather than a fix that can be shipped as it’s a known limitation. 

#gutenberg, #hallway-hangout, #outreach, #site-editor

JSX in WordPress 6.6

WordPress 6.6 introduces the possibility for developers to use the new React JSX transform that was first released in ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. 17. 

How to use the new JSX in WordPress 6.6

Your build scripts need to apply the following changes in the built files:

  • Add the react-jsx-runtime to your script dependencies.
  • Use ReactJSXRuntime.jsx global as the output of your JSX calls.

In general, this is not something you do manually in your code base. Instead, you’ll use a build tool. The @wordpress/scripts, @wordpress/babel-preset-default and  @wordpress/dependency-extraction-webpack-plugin npm packages have been upgraded to apply these transformations automatically.

Build Tools Compatibility and upgrade path

If you’re using the JSX syntax in your code base, and as long as you don’t update your dev dependencies (including @wordpress/scripts, @wordpress/babel-preset-default or @wordpress/dependency-extraction-webpack-plugin), you will continue to use the old JSX transform. This will allow your 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 built files to be compatible with WordPress 6.5, earlier versions and WordPress 6.6 as well.

When you’re ready to make WordPress 6.6 the minimum supported version of your plugin, you can update the following dependencies to use the new JSX transform.

  • @wordpress/scripts from version 28.
  • @wordpress/babel-preset-default from version 8.
  • @wordpress/dependency-extraction-webpack-plugin from version 6.

Going forward

The new JSX transform comes with performance improvements and optimization. 

Note that the React team will deprecate the old JSX transform in the upcoming React v19 release (currently in RC). 


Thank you @ramonopoly @justlevine for contributing to and reviewing this post.

#6-6, #dev-note, #dev-notes, #dev-notes-6-6

Interactivity API in 6.5

The Interactivity 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. provides a standard way for developers to add interactions to the frontend of their blocks.

This standard aims to make it easier for developers to create rich, interactive user experiences, from simple cases like counters or pop-ups to more complex features like instant page navigation, instant search, carts, or checkouts.

Blocks can share data, actions, and callbacks between them. This makes communication between blocks simpler and less error-prone. For example, clicking on an “add to cart” 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. can seamlessly update a separate “cart” block.

To understand better the reasoning behind it, you can take a look at the original proposal, where it is explained in more detail.

More information about it can be found in the merge announcement, the status update post, and the Trac ticket for the Interactivity API.

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. covers the APIs included in 6.5 and how to use the Interactivity API.

How to create interactions using the Interactivity API

It’s important to highlight that the block creation workflow doesn’t change.

Until now, WordPress has been intentionally unopinionated about the different solutions used on the frontend of blocks. The Interactivity API changes that. It adds a new standard way to easily add frontend interactivity to blocks while the APIs handling the Block Editor remain the same.

You need first to declare its compatibility with the API by adding the interactivity property inside  supports, in the block.json file:

"supports": {
    "interactivity": true
},

Refer to the Block Editor handbook to get a more detailed description of the interactivity support property.

The Interactivity API script requires using the new script modules coming in WordPress 6.5, so blocks should enqueue the 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/. by using viewScriptModule:

// block.json
{
   ...
   "viewScriptModule": "file:./view.js"
}

You can easily scaffold and test an interactive block following this quick start guide, which explains how to use a CLICLI Command Line Interface. Terminal (Bash) in Mac, Command Prompt in Windows, or WP-CLI for WordPress. command to speed up this process.

With that in mind, in order to add interactivity to blocks powered by the Interactivity API, developers would need to:

  1. Add directives to the markup to add specific interactions to the block.
  2. Create a store with the logic (state, actions, or callbacks) for interactivity.

Let’s use a simple example to explain it: a button that shows and hides some text. Let’s also send a message in the console whenever the button is hidden or revealed.

1. Add the directives

Directives are custom attributes that are added to the markup of your block to add interactions to its DOM elements. They are placed in the render.php file (for dynamic blocks).

The very first step is to add the data-wp-interactive directive. This is used to “activate” the Interactivity API in a DOM element and its children, and its value must be the unique namespace of your 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 or block:

<div data-wp-interactive="myPlugin">
    <!-- Interactivity API zone -->
</div>

The rest of the directives can be added with the desired interactions.

// render.php
$context = array('isOpen' => false);
<div
  data-wp-interactive='myPlugin'
  data-wp-watch="callbacks.logIsOpen"
>
  <button>
    Toggle
  </button>
  <p id="p-1">
    This element is now visible!
  </p>
</div>

Additionally, directives can also be injected dynamically using the HTML Tag Processor.

Don’t worry if you don’t understand how it works yet. So far, the important part is that the example above uses directives like wp-on and wp-bind to add interactivity to the HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers.. This is the list of directives available in WordPress 6.5:

You can find a deeper explanation of each directive and examples of how to use it in the relevant links.

  • wp-interactive: This attribute must be set to the unique identifier of your plugin or block in order for it to use the Interactivity API.
  • wp-context: It provides a local state available to a specific HTML node and its children. It accepts stringified 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. as a value. It’s recommended to use wp_interactivity_data_wp_context() to set it in PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher.
  • wp-bind: It allows HTML attributes to be set on elements based on a boolean or string value. It follows the syntax data-wp-bind--[attribute]. (like data-wp-bind--value)
  • wp-class: It adds or removes a class to an HTML element, depending on a boolean value. It follows the syntax data-wp-class--[classname].
  • wp-style: It adds or removes inline style to an HTML element, depending on its value. It follows the syntax data-wp-style--[css-property].
  • wp-text: It sets the inner text of an HTML element. It only accepts strings as the parameter.
  • wp-on: It runs code on dispatched DOM events like click or keyup. Its syntax is data-wp-on--[event] (like data-wp-on--click or data-wp-on--keyup).
  • wp-on-window: It allows to attach global window events like resize, copy, focus and then execute a defined callback when those happen. Its syntax is data-wp-on-window--[window-event] (like data-wp-on-window--resize or data-wp-on-window--languagechange).
  • wp-on-document: It allows to attach global document events like scroll, mousemove, keydown and then execute a defined callback when those happen. Its syntax is data-wp-on-document--[document-event] (like data-wp-on-document--keydown or data-wp-on-document--selectionchange).
  • wp-watch: It runs a callback when the node is created and runs it again when the state or context changes.
  • wp-init: It runs a callback only when the node is created.
  • wp-run: It runs the passed callback during node’s render execution.
  • wp-key: It assigns a unique key to an element to help the Interactivity API identify it when iterating through arrays of elements.
  • wp-each: It is intended to render a list of elements.
  • wp-each-child: Ensures hydration works as expected, is added automatically on the server processing of wp-each directive.

2. Create the store

The store is used to create the logic that will link the directives with the data used inside that logic.

All stores are referenced by a unique namespace, separating the logic and avoiding name collisions between different store properties and functions.

If there are multiple stores defined with the same namespace, they will be merged into a single store.

The store is usually created in the view.js file of each block, although the state can be initialized in the backend, for example, in the render file of the block.

The state is a global object, available to all HTML nodes of the page. It is defined by the store() function. If you need a local state for just a node and its children, check the context definition.

The object can accept any property, in order to keep consistency between projects, this convention is recommended.

  • State: Defines data available to the HTML nodes of the page. Properties inside the state will be available globally. If you need to edit them, the recommended way is by using getters.
    • Derived State. If you need a modified version of any state property, getters are the recommended approach (more on deriving state below).
  • Actions: Usually triggered by the data-wp-on directive (using event listeners).
  • Callbacks: Automatically reactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. to state changes. Usually triggered by data-wp-on-window, data-wp-on-document or data-wp-init directives.

Returning to our example, this could be a simple store in one block, a global state has been added for having a complete sample of how a store could look like.

// view.js
import { store, getContext } from "@wordpress/interactivity";

const { state } = store( 'myPlugin', {
 state: {
  likes: 0,
  getDoubleLikes() {
    return 2 * state.likes;
  }
 },
  actions: {
    toggle: () => {
      const context = getContext();
      context.isOpen = !context.isOpen;
    },
  },
  callbacks: {
    logIsOpen: () => {
      const context = getContext();
      // Log the value of `isOpen` each time it changes.
      console.log(`Is open: ${context.isOpen}`);
    },
  },
});

There can be cases where only actions and callbacks are defined in the store.

DOM elements are connected to data stored in the state and context through directives. If data in the state or context change directives will react to those changes, updating the DOM accordingly (see diagram).

When creating the store, there are some important things to be aware of:

Using derived state

Derived state uses getters to return a computed version of the state. It can access both state and context.

// view.js

const { state } = store( "myPlugin", {
  state: {
    amount: 34,
    defaultCurrency: 'EUR',
    currencyExchange: {
      USD: 1.1,
      GBP: 0.85,
    },
    get amountInUSD() {
      return state.currencyExchange[ 'USD' ] * state.amount,
    },
    get amountInGBP() {
      return state.currencyExchange[ 'GBP' ] * state.amount,
    },
  },
} );

Accessing the store by destructuring

The store contains all the store properties, like state, actions, or callbacks. They are returned by the store() call, so you can access them by destructuring it:

const { state, actions, callbacks } = store( "myPlugin", {
  // ...
} );

Note that context is not part of the store and is accessed through the getContext function.

If you want to take a deeper view about how the store() function works, feel free to check the function documentation here.

Async actions

Async actions should use generator functions instead of async/await or promises. The Interactivity API needs to be able to track async behavior in order to restore the proper scope. Otherwise, getContext may return stale values if it was updated concurrently with the async operation. Instead of awaiting the promise, yield it from the generator function, and the Interactivity API will handle awaiting its completion.

So, instead of:

const { state } = store("myPlugin", {
  state: {
    get isOpen() {
      return getContext().isOpen;
    },
  },
  actions: {
    someAction: async () => {
      state.isOpen; // This is the expected context.
      await longDelay();
      state.isOpen; // This may not get the proper context unless it's properly restored.
    },
  },
});

function longDelay() {
  return new Promise( ( resolve ) => {
    setTimeout( () => resolve(), 3_000 );
  } );
}

The store should be:

const { state } = store("myPlugin", {
  state: {
    get isOpen() {
      return getContext().isOpen;
    },
  },
  actions: {
    someAction: function* () {
      state.isOpen; // This is the expected context.
      yield longDelay(); // With generators, the caller controls when to resume this function.
      state.isOpen; // This context is correct because the scope was restored before resuming after the yield.
    },
  },
});

function longDelay() {
  return new Promise( ( resolve ) => {
    setTimeout( () => resolve(), 3_000 );
  } );
}

If you want to take a deeper look at the example, check the API reference.


Working with other namespaces

Interactive blocks can share data between them, unless they are private stores.

Directives

In order to access the store of a different namespace in a directive, add the namespace before the directive value. For example:

<!-- This accesses the current store -->
<div data-wp-bind--id="state.text"></div>
<!-- This accesses the "otherPlugin" store -->
<button data-wp-bind--id="otherStore::state.text">>Button</button>

Context

Context from a different namespace can be accessed by providing the desired namespace as an argument to getContext( namespace ):

import { getContext } from "@wordpress/interactivity";
 
const otherPluginContext = getContext( "otherPlugin" );

Store

Like context, different stores can be accessed by passing the desired namespace as an argument: 

const { state: otherState, actions: otherActions } = store( "otherPlugin" );

Private stores

A store can be “locked” to prevent its content from being accessed from other namespaces. To do so, set the lock option to true in the store() call, like in the example below. When the lock is set, subsequent executions of store() with the same locked namespace will throw an error, meaning that the namespace can only be accessed where its reference was returned from the first store() call. This is especially useful for developers who want to hide part of their plugin stores so it doesn’t become accessible for extenders.

const { state } = store("myPlugin/private", {
  state: {
      messages: [ "private message" ]
    } 
  },
  { lock: true }
);

// The following call throws an Error!
store( "myPlugin/private", { /* store part */ } );

There is also a way to unlock private stores: instead of passing a boolean, you can use a string as the lock value. Such a string can then be used in subsequent store() calls to the same namespace to unlock its content. Only the code with the lock string will be able to access the protected store. This is useful for complex stores defined across multiple files.

const { state } = store("myPlugin/private", {
  state: {
      messages: [ "private message" ]
    }
  },
  { lock: PRIVATE_LOCK }
);

// The following call works as expected.
store( "myPlugin/private", { /* store part */ }, { lock: PRIVATE_LOCK } );

Interactivity API client methods

The following methods are for use in JavaScript and are provided by the wordpress/interactivity script module available in WordPress 6.5.

getContext()

The context defined with the data-wp-context attribute can be retrieved with the getContext function:

const { state } = store( "myPlugin", {
  actions: {
    someAction() {
      const context = getContext();
      const otherPluginContext = getContext( 'otherPlugin' );
      // ...
    }
  }
} );

Handbook description.

getElement()

Retrieves a representation of the element where a function from the store is being evaluated. This representation is read-only, and contains a reference to the DOM element and its attributes.

Handbook description.

getConfig()

Retrieves a configuration object that was previously defined in the server via wp_interactivity_config() function.

Configuration is immutable on the client, it cannot be modified. You can get an example later in this document.

store()

Creates the store used to link the data and actions with their respective directives. Check the main section for more information.

withScope()

Actions can depend on the scope when they are called, e.g., when you call getContext() or getElement().

When the Interactivity API runtime execute callbacks, the scope is set automatically. However, if you call an action from a callback that is not executed by the runtime, like in a setInterval() callback, you need to ensure that the scope is properly set. Use the withScope() function to ensure the scope is properly set in these cases.

An example, where actions.nextImage would trigger an undefined error without the wrapper:

store('mySliderPlugin', {
	callbacks: {
		initSlideShow: () => {
		    setInterval(
				withScope( () => {
					actions.nextImage();
				} ),
				3_000
			);
		}
	},
})

Interactivity API server functions

These are the PHP functions the Interactivity API includes:

wp_interactivity_state( $store_namespace, $state )

It is used to initialize the state on the server and ensure that the HTML sent by it, and the HTML after the client hydration are the same. And it also allows you to use any WordPress API like coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. translations.

// render.php

wp_interactivity_state( "movies", array(
      "1" => array(
        "id" => "123-abc",
        "movieName" => __("someMovieName", "textdomain")
      ),
) );

It receives two arguments, a string with the namespace that will be used as a reference and an associative array containing the values.

The state defined on this function gets merged with the stores defined in the view.js files.

wp_interactivity_data_wp_context( $context, $store_namespace )

Generates a data-wp-context attribute ready to be server side rendered. This function escapes the array to prevent external attacks, apart from any error that may appear when writing JSON strings manually.

$context is an array containing the keys and values of the context.

$store_namespace allows referencing different stores, and is empty by default.

<?php
 $context = wp_interactivity_data_wp_context(
  array(
    'post_id' => get_the_ID(),
    'show' => true,
  )
 )
?>
<div <?php echo $context ?> >
  My interactive div
</div>

Will return

<div data-wp-context="{"post_id":1,"show":true}">
  My interactive div
</div>

wp_interactivity_config( $store_namespace, $config )

Sets or gets configuration for an interactivity store. An immutable copy of the configuration can be read by the client.

Consider config as a global setting that can affect the full site and won’t be updated on client interactions. For example, determining if a site can handle client-side navigation or not.

<?php
wp_interactivity_config( 'myPlugin', array( 'setting' => true ) );
 $config = wp_interactivity_config( 'myPlugin' );
?>
<div>
  My interactive div
</div>

This config can be retrieved in the client:

// view.js

import { getConfig } from '@wordpress/interactivity';

const { setting } = getConfig('myPlugin');
console.log( 'setting => ', setting);

wp_interactivity_process_directives( $html )

Processes directives within HTML content, updating the markup where necessary.

This is the core functionality of the Interactivity API. It’s public so that any HTML can be processed, not just blocks.

For blocks with supports.interactivity, directives are automatically processed. Developers do not need to call wp_interactivity_process_directives in this case.

<?php
$html_content = '<div data-wp-text="myPlugin::state.message"></div>';

wp_interactivity_state( 'myPlugin', array( 'message' => 'hello world!' ) );

// Process directives in HTML content.
$processed_html = wp_interactivity_process_directives( $html_content );

// output: <div data-wp-text="myPlugin::state.message">hello world!</div>

Relevant links

Props to @gziolo, @darerodz, @santosguillamot, @luisherranz and @jonsurrell for technical review.

Props to @leonnugraha for copy review.

#6-5, #dev-notes, #dev-notes-6-5, #interactivity-api

WordPress 6.5.4: An upcoming maintenance release

A number of 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 have reported that the fix introduced as a part of #60992 has not sufficiently helped their users, therefore #61269 is being proposed as a short cycle fix. In order to get this fix released quickly, WordPress 6.5.4 is being planned with the following schedule.

  • 30 May 2024 – Release Candidaterelease candidate One of the final stages in the version release cycle, this version signals the potential to be a final release to the public. Also see alpha (beta). made available and announced here on the make/coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. site.
  • 5 June 2024 – Final release made available.

Specific times will be decided in advance and adjustments to the schedule may be made. All adjustments will be noted in this post.

Minor or Maintenance releases of WordPress are intended as bugbug A bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority.-fix only releases. If you have a 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. that you think should be considered, please put it in the 6.5.4 milestone. If you have a 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/ issue, please add it to the 6.5.x Editor Tasks board. If you lack bug gardening capabilities and have a ticket or issue you wish to highlight for 6.5.4, please add a comment here.

Note: except in extreme situations, only bug fixes will be considered and generally only bugs that have been introduced during the 6.5 cycle.

Get involved with 6.5.4

Each of the open tickets in the milestone is going to require development work along with testing and review. Additionally, while the intent is for no new translated strings in this release, some locales have strings in 6.5 in need of translation.

General coordination for the release will happen in the #6-5-release-leads channel and decisions around code for the release will be made in the #core room.

This minor releaseMinor Release A set of releases or versions having the same minor version number may be collectively referred to as .x , for example version 5.2.x to refer to versions 5.2, 5.2.1, 5.2.3, and all other versions in the 5.2 (five dot two) branch of that software. Minor Releases often make improvements to existing features and functionality. will be led by @hellofromtonya, @costdev, and myself (@jorbin). If there are editor related issues that need to be included, @grantmkin has agreed to lead those as well.

Thanks to @joemcgill, @costdev, @grantmkin, and @hellofromtonya for prepublication review.

#6-5, #6-5-x

Proposal: Server to client data sharing for Script Modules

Abstract

Script Modules were introduced in WordPress 6.5. wp_add_inline_script is often used to initialize or make data available to Scripts. Feedback on Script Modules and explorations suggest this would be a useful feature for Script Modules, but nothing exists at this time. This post will describe the problem in detail and propose a solution. The proposed solution consists of three main points:

  • A new filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. runs for each Script Module that is enqueued or in the dependency graph. This filter allows arbitrary data to be associated with a given Script Module and added to the rendered page.
  • Script Module data is embedded in the page as 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. in a <script type="application/json"> 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.).
  • Script Modules are responsible for reading the data and performing their own initialization.
Read more: Proposal: Server to client data sharing for Script Modules

The feedback period will end 2024-05-24 (Friday, May 24). Please provide any feedback before then.

This post will use “scripts” to refer to WP Scripts and “modules” to refer to WP Script Modules.

Scripts or modules?

Most 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/. for WordPress is probably using scripts unless it was specifically compiled as a module. Modern JavaScript is often authored using import apiFetch from '@wordpress/api-fetch', which is module syntax. Until very recently, WordPress build tooling has always removed the module syntax and compiled a script.

Only the most recent WordPress version 6.5 introduced support for modules. WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. includes exactly two modules to expose functionality at this time: @wordpress/interactivity and @wordpress/interactivity-router. JavaScript that uses the Interactivity 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. is probably a module.

This post will talk about a common script dependency, wp-api-fetch. The @wordpress/api-fetch module mentioned in this post is hypothetical; it does not exist at this time.

A note about modules

It’s important to know a few things about scripts versus modules in the context of this post. A few key differences:

  • Scripts and their dependencies will be executed as the page is parsed even if a dependency is never directly used.
  • Script “exports” are attached to the window object, e.g. wp-api-fetch is available as window.wp.apiFetch.
  • Modules will execute after the page has finished parsing.
  • Module dependencies can be loaded on demand.
  • Modules have true encapsulation, using import and export to share values.
More about scripts and modules…

Scripts that are either enqueued or are dependencies of enqueued scripts will be added to the page as script tags, like <script src="path/to/script.js">. The browser will fetch and execute these scripts before it continues to parse the page. There are attributes like async and defer that can change how the browser executes scripts.

Modules that are enqueued will appear on the page as script tags of type module, like <script src="path/to/module.js" type="module">. Processing of modules is deferred, they will be executed after the whole document has been parsed. The async attribute will cause a module to execute in parallel as the document is parsed. WordPress Script Modules do not use async at this time.

Modules that are in the dependency graph of enqueued modules will appear in an importmap. This is a mapping of names to URLs so that a browser knows what module to fetch when it sees an import. It’s what associates the module used in a statement like import "a-module"; with a URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org { "imports": { "a-module": "path/to/a-module.js" } }.

The problem

Scripts often require some initialization or other data to work correctly in WordPress. The wp-api-fetch script is a good example, it requires a significant amount of configuration. For example, Core uses the following inline script to initialize wp-api-fetch so it can send requests to the appropriate place:

$scripts->add_inline_script(
	'wp-api-fetch',
	sprintf(
		'wp.apiFetch.use( wp.apiFetch.createRootURLMiddleware( "%s" ) );',
		sanitize_url( get_rest_url() )
	),
	'after'
);

This snippet uses PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher to create a string of JavaScript code with some data from PHP embedded. This will be included in a script tag that appears immediately after the script tag for wp-api-fetch, something like this:

<script src="path/to/wp-api-fetch.js"></script>
<script>
// The JavaScript code is printed here:
wp.apiFetch.use( wp.apiFetch.createRootURLMiddleware( "…/index.php?rest_route=/" ) );
// More code may follow from other calls to `wp_add_inline_script`…
</script>

Notice that the JavaScript depends on wp-api-fetch, it imperatively calls wp.apiFetch.use(…). That same approach with a hypothetical @wordpress/api-fetch module would look something like this:

<script type="importmap">
{ "imports": { "@wordpress/api-fetch": "…url/to/api-fetch-module.js" } }
</script>
<script type="module">
import apiFetch from '@wordpress/api-fetch';
wp.apiFetch.use( wp.apiFetch.createRootURLMiddleware( "…/index.php?rest_route=/" ) );
</script>

In this approach, the initialization module would fetch and execute the @wordpress/api-fetch module just to initialize it! That eliminates one of the important advantages of modules, their ability to load on-demand. 🤔 It looks like this imperative initialization isn’t a good fit for modules. Let’s see if there’s a better solution…

The proposal

Here are some requirements that arise from the naive implementation:

  • Modules should be fetched and initialized on demand.
  • Modules should be responsible for their own initialization when they’re executed.
  • Variables should be scoped to modules and not pollute the global namespace.
  • The data should introduce minimal overhead.

Add server data via filters

Filters provide a nice method to collect the data needed by modules. The WP_Script_Modules class introduces a new filter that runs for each module that is enqueued or present in the dependency graph. Adding or modifying data for a module looks like this:

add_filter(
	'scriptmoduledata_@wordpress/api-fetch',
	function ( $data ) {
		$data['rootURL'] =  sanitize_url( get_rest_url() )
		return $data;
	}
);

Multiple filters can be added to add or modify the data exposed to the script, and if no data is added, nothing will be serialized on the page for the client. It’s also worth mentioning that no JavaScript code is written in PHP, a nice improvement over wp_add_inline_script which requires valid JavaScript to be added.

A drawback to this approach is that all the data passed must pass through JSON. Data without a valid JSON representation is not supported by default.

Use an inert script tag to expose data on the client

The data is embedded it in the HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. in a script tag:

<script id="scriptmoduledata_@wordpress/api-fetch" type="application/json">
{ "theData": "JSON Serializable data can be shared" }
</script>

This script tag is effectively ignored by the browser because of its type attribute. This approach is an example on MDN of how to embed data in HTML and it’s already used in WordPress to pass Interactivity API data to the client.

Because modules are always deferred, it should be safe to print these script tags at the bottom of the page. They should have limited impact on page load because the browser will not parse or execute the contents.

Modules read data from the script tag

This script tag doesn’t do anything on its own. The module is responsible for getting the data and performing its initialization when it executes:

if ( typeof document !== 'undefined' ) {
	const serializedData = document.getElementById(
		'scriptmoduledata_@wordpress/api-fetch'
	)?.textContent;
	if ( serializedData ) {
		let config = null;
		try {
			config = JSON.parse( serializedData );
		} catch {
			// there was a problem parsing the serialized data
		}
		performInitialization( config );
	}
}
function performInitialization( config ) {
	if ( config?.rootURL ) {
		registerMiddleware( createRootURLMiddleware( config.rootURL ) );
	}
	// etc.
}

This approach is used by @wordpress/interactivity to retrieve store data on the client.

Try it!

I’ve prototyped this proposal in the following PRs:

  • WordPress-develop PR 6433 applies the filters and adds the necessary filters to expose data to @wordpress/api-fetch. The proposal in this post is contained in this PR.
  • Gutenberg PR 60952 builds and registers the @wordpress/api-fetch module. This PR is helpful for testing, but is beyond the scope of this post.

Try it in the WordPress Playground here. If you run the following JavaScript in the inspector console —make sure you pick the JavaScript context, something like wp (scope:abc123)— you’ll see the @wordpress/api-fetch module log some initialization when it’s imported and then work as expected:

const { apiFetch } = await import( '@wordpress/api-fetch' );
await apiFetch( { path: '/wp/v2/block-types' } )
Screenshot of browser console showing the `@wordpress/api-fetch` module initializing on demand and being used to make a REST request.

Relevant links

Props @youknowriad, @cbravobernal, @bph, and @andronocean for review.

#javascript, #script-loader

Roadmap to 6.6

WordPress 6.6 is set to be released on July 16, 2024. With a slightly shorter cycle, this release heavily builds on the foundation of the last with some new items, like section styles and overrides in synced patterns, and loads of enhancements to features that landed in the last few releases, including the Font Library and Interactivity 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.. Data Views, the first taste of the admin redesign work introduced in 6.5, continues to evolve with new layout options, a combined template part and pattern experience, and more readily accessible management sections. Finally, design tools take center stage with everything from grid layout support to section styles to more power baked into style variations out of the box. 

As always, what’s shared here is being actively pursued, but doesn’t necessarily mean each will make it into the final release of WordPress 6.6.

For a more detailed look at the work related to the 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. editor, please refer to the 6.6 board and review the currently open Iteration issues. After a recent organization effort, Iteration issues are meant to reflect active work that’s been scoped down for a major releasemajor release A release, identified by the first two numbers (3.6), which is the focus of a full release cycle and feature development. WordPress uses decimaling count for major release versions, so 2.8, 2.9, 3.0, and 3.1 are sequential and comparable in scope.. To get a sense of some of what’s being worked on both for this release and beyond, check out the demos shared in a recent hallway hangout.

Foundational experience

Advancing the new Data Views in the Site Editor

Building on an initial launch in 6.5, the new views in the Site Editor continue to be refined and advanced. This includes work to bring the various management pages forward (manage all templates, manage all template parts, manage all pages) so those options are immediately seen when visiting the respective sections, reducing the number of steps to access important information. For pages, a new side by side layout will be introduced so one can see both a list of all pages and a preview of the currently selected page. For patterns, template part management will be removed and integrated into the current overall patterns section. Interspersed within all of these larger changes are smaller enhancements in functionality and feel. 

Manage template screen showcasing the side by side layout with navigation on the far left, a list of templates in the middle, and a larger preview window on the right showing the current template.

Follow this tracking issue for more information. 

Zoom out to compose with patterns

A few different initiatives are coming together to allow one to focus on building with patterns rather than granular block editing, including advancing contentOnly editing and zoomed out view. Key features planned include:

  • A zoomed out experience in the editor when inserting patterns to facilitate high level overview of the site.
  • Ability to shuffle top level patterns within a template in order to quickly explore alternative patterns.
  • Ability to manipulate patterns in the template via moving, deleting, etc while zoomed out. 
  • Improvements to UXUX User experience for dragging patterns (e.g. vertical displacement).

Taken together, this work aims to offer a first step towards a new way to interact with and build with patterns. Some questions remain including whether zooming out will be invoked in certain situations, like the patterns tab of the Inserter, or if it’s something that could be toggle on/off as one wants. 

Pattern inserter open to Banner patterns with the content of the site zoomed out, showing more of the template that the pattern is going to be added to.

Follow this iteration issue for more information. 

View inherited style values

Knowing where a block’s style comes from is key to knowing where a change might need to be made. For 6.6, work is underway to show locally the value that a block inherits globally, when applicable. This means that, for example, if you set a paragraph to always have blue text in Styles, every paragraph you added will show blue text and the block settings will show the blue color as the chosen text color. This is in contrast to today’s confusing experience, where it shows a circle with a line through it, to indicate that no local color has been set despite the block inheriting it globally. 

Follow this issue for more information. 

Unifying editor experiences, including publish flow

This is both a technical and design effort, consolidating shared code and creating a single, coherent flow across the post and site editors for common tasks. The more noticeable and big pieces will be seen in a unified publish flow and a new singular “summary” inspector panel, which will also be reused within the site editor when you are bulk editing. 

Follow this iteration issue for aligning features and this tracking issue for the inspector controls for more information. 

Design tools

Mix and match typography and color palettes from all styles variations 

Style variations allow you to change the look and feel of your site, all while using the same theme. To build on the design possibilities of a block theme with style variations, 6.6 aims to add the ability to mix and match the color and typography styles of each individual style variations. This means the eight community created style variations baked into the Twenty Twenty-Four theme turns into 48 styling combinations, thanks to the six typography presets and eight color presets available. Add in more typography options thanks to the Font Library and the optionality available is immense, alongside all of the granular tinkering you want to do. This evolution in style variation possibilities will work out of the box with all block themes with style variations with no additional opting in or adjustments on the theme author’s end. 

Follow this iteration issue for more information. 

Syncing specific blocks and attributes of patterns

Building upon synced patterns, overrides in synced patterns would allow users to ensure a synced layout and style across patterns while allowing each instance of the pattern to have customized content. This allows for consistency in design across different pieces of content. For instance, consider a testimonial pattern in a grid. With the enhanced feature, someone can insert this testimonial pattern into multiple posts, ensuring that the layout and styling components, such as the overall design of the recipe card, remain consistent across instances. Meanwhile, the content, such as Name, Image, and Role, would be local to each instance allowing for individual customization. Additionally, folks would then be able to revisit and modify the design of the overall testimonial pattern without affecting the content in existing instances. To get a sense of the current work happening here, check out the “overrides in synced patterns” demo from a recent hallway hangout below:

Follow this iteration issue for more information 

Expanding block style variations for more styling options 

Through work to extend the block style variations mechanism, 6.6 is set to introduce the ability for theme authors to define style options for sections of multiple blocks, including inner blocks. With just a few clicks, folks using block themes that add this functionality could quickly change just a section of a page or template to predefined styles that an author provided, like a light or dark version of a section. This feature is coming together thanks to work to expand the block style variations API. There are a few ways folks are aiming to offer this functionality:

  • Programmatically via gutenberg_register_block_style
  • By standalone 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. partials within a theme’s /block-styles subdirectory
  • Via theme style variations defining block style variations under styles.blocks.variations.

To see a very early look at this work, check out the “Section Styles” demo from a recent hallway hangout.

Follow this iteration issue for more information. 

Improvements to Grid Layout

Grid is a new layout variation for the Group block that allows you to display the blocks within the group as a grid, offering new flexibility. There are two options for the Grid layout:

  • “Auto” generates the grid rows and columns automatically using a minimum width for each item. 
  • “Manual” allows specifying the exact number of columns.

Outside of expanding functionality, including trying to implement drag and drop resizing, work is also underway to improve using layout tooling in general to make it simpler and clearer to accomplish what you want.

Follow this tracking issue for more information and/or join the dedicated #feature-grid slackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel. 

Refining the Font Library 

To build on its debut in 6.5, the Font Library will continue to see bugbug A bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. fixes and enhancements based on incoming feedback. This work will be less about adding new functionality and more about refining what’s landed. 

Follow this iteration issue for more information. 

Additional supports

A selection of smaller efforts come together to provide more design options directly in the editor:

Adoption pathways

Bringing the Site Editor experience for Pattern management to Classic Themes

Thanks to some internal code changes, the path is set to enable Classic Themes to have access to the new Patterns experience that the Site Editor provides. This will provide an upgraded, modern experience of managing and creating patterns.

Follow this iteration issue for more information. 

Continued performance improvements

This release cycle, a variety of initiatives are focused on improved loading times, especially template loading with improved caching of theme.json, block templates and computed styles as well as optimizing autoload options. Research and initial work to address potential improvements to the INP (Interaction to next pain) metric is also continuing in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. and the Interactivity API. In addition, ongoing performance improvements for the editor for this release are being tracked in this iteration issue, including major improvements to template loading.

Outside of the above efforts, work continues to improve performance tooling, including our automated performance test actions running in both 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/ and core. The current effort is focused on making the performance tests more consistent, robust and reliable and on providing an easy-to-use GitHub action developers can leverage to implement the performance tests in their own 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 or theme.

API iterations

Various APIs recently introduced in the last few releases are all slated for continued upgrades.

Interactivity API

The Interactivity API provides a standard way to allow developers to add interactivity to the frontend of their blocks. After the release of the initial version of the Interactivity API in 6.5, this next round of work is focused solely on enhancing the developer experience with better test coverage and code quality, improved error reporting, debugging tools, and fixing reported bugs.

Follow this iteration issue for more information and/or join the dedicated #core-interactivity-api slack channel. 

Block HooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same.

Introduced in WordPress 6.4 and iterated upon in 6.5, the Block Hooks API is an extensibility mechanism that allows you to dynamically insert blocks into block themes. At this stage of maturity, work is underway to help determine a proper UIUI User interface for hooked blocks and continued improvements