Miscellaneous developer changes in WordPress 6.5


Table of contents


Administration

A new_admin_email_subject hook is introduced, which filters the subject line of the email sent when a change of site adminadmin (and super admin) email address is initiated. (59250)

The default cursor style has been adopted for labels when its associated form controls are disabled, which improves 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). (59733)

Bootstrap/Load

Two new functions have been introduced to check whether WordPress is serving a REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think โ€œphone appโ€ or โ€œwebsiteโ€) can communicate with the data store (think โ€œdatabaseโ€ or โ€œfile systemโ€) https://developer.wordpress.org/rest-api/ request: wp_is_serving_rest_request() and wp_is_rest_endpoint(). Both functions should only be used after the parse_request action. 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. wp_is_rest_endpoint has been added to alter the return value of the wp_is_rest_endpoint() function. (42061)

Canonical

A new wp_admin_canonical_url filter hook is introduced to modify the admin canonical url value. (59545)

Editor

A new metadata global attribute has been added, which is needed for scenarios such as allowing the user to assign custom names to blocks, or for making 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. 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. work with user-modified templates/parts/patterns. (59797)

A new data field allowed_blocks that specifies block types has been added in block.json for block registration and REST API. (60403)

New video and audio pattern categories have been added for better organization of patterns. (60342)

A new setting allowCustomContentAndWideSize that disables layout content and wide size controls has been added to WP_Theme_JSON class. (60133)

Default duotone styles is allowed if not explicitly disabled in theme.json. (60136)

An aspect ratio dimensions.aspectRatio block support feature has been added, with support for both Group and Cover blocks. (60365)

Shadow block support via direct attribute has been replaced with support via style attribute instead. (60377)

The capabilitycapability Aย capabilityย is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on theirย role. For example, users who have the Author role usually have permission to edit their own posts (the โ€œedit_postsโ€ capability), but not permission to edit other usersโ€™ posts (the โ€œedit_others_postsโ€ capability). to parse CSSCSS Cascading Style Sheets. custom properties for fontSize and fontFamily has been added in WP_Style_Engine. (59982)

background-repeat has been added to the list of safe CSS properties for KSES. (60132)

viewStyle property has been added to block.json. This change brings block styles in parity with block scripts. (59673)

Pattern blockโ€™s overrides attribute data structure has been updated and renamed to content. (60456)

Asset registration file .asset.php has been made optional for blocks. (60460)

Support for deferred block variation initialization on the server has been added, which improves performance. The WP_Block_Type object has added a new property, variation_callback, which can be used to register a callback for building variation data only when the block variations data is needed. The WP_Block_Type::variations property has been made private. (59969)

Emoji

twitter/twemoji has been replaced with jdecked/twemoji v15.0.3, which adheres to the Unicode 15 spec and adds support for all Emoji introduced in Emoji 15.0. (57600)

General

$schema property has been added to block.json and theme.json files, which help ensure these files conform to expectations. (60255)

Media

Media icons are .svg by default: .png icon files in the media library have been replaced with .svg versions, which improves sharpness in different screen resolution devices. An argument for wp_mime_type_icon() to control the file type returned has been added. CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. usage now always returns an .svg file while maintaining backwards compatibility for any extended usage that expects a .png file. (31352)

Rest API

Terms can be assigned when creating attachments. (57897)

Information that is captured by the fatal error handler within a REST API request will now be provided when WP_DEBUG_DISPLAY is set to true. This additional data, appended under the new key error_data, can facilitate more thorough debugging for REST API errors. (60014)

Error handling in REST 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. fields has been improved to collect all errors in a WP_Error object and continue execution after encountering the first error. This enhancementenhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. enables handling and displaying of multiple errors in a single response, which improves the debugging process. (48823)

original_source and author_text data fields have been added to the templates REST API. (60358)

Shortcodes

Shortcode_parse_atts() will now always return an array, which also improves developer experience as the return value does not have to be manually checked in the shortcodeShortcode A shortcode is a placeholder used within a WordPress post, page, or widget to insert a form or function generated by a plugin in a specific location on your site. itself. (59249)

Sitemaps

The โ€œLast Modifiedโ€ (lastmod) 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.) has been added for the individual posts and the homepage entries in the sitemap. (52099)

Themes

A new โ€˜theme_filesโ€˜ cache group, setup as a global cache group, has been added to block pattern caches. On a multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site networknetwork (versus site, blog), there will now be a single cache for block pattern data per theme, which allows block pattern caches to be shared between sites on a network and result in less repeated data in the object cache. (60120)

Users

Profile page color palettes:

On a userโ€™s profile page, the color palette options are now displayed in <div> elements instead of tables.

Styles and scripts that target selectors such as table.color-palette or .color-palette td may need to be updated. To support WordPress versions both before and after this change, a 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. can use the new .color-palette-shade class:

.color-palette td,
.color-palette-shade {
border-color: #fff;
}

Props to @sabernhardt for the 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..
(53157)

Props to @davidbaumwald for technical review, to @get_dave and @youknowriad for technical review (Editor), to @jorbin for technical/copy review.

#6-5, #dev-notes, #dev-notes-6-5

Unblocking WP6.5 – Font Library and Synced Pattern Overrides

A number of contributors have flagged a stalemate on a couple of different topics for WP6.5 this week. I want to first thank everyone who joined in the discussions 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 by the repository owner. https://github.com/, 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/, and elsewhere. There were a lot of well-reasoned and important concerns raised and it was an excellent example of the way open sourceOpen Source Open Source denotes software for which the original source code is made freely available and may be redistributed and modified. Open Source **must be** delivered via a licensing model, see GPL. works in the open. Over the last few days, Iโ€™ve discussed the suggested approaches with several coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. and core-editor contributors, including pros, cons, and side effects. Weโ€™ve reached a consensus on a path forward on both the Font Library and the issue with Synced Pattern Overrides.

Font Library

The font library portion of this post has been superseded by the post WordPress 6.5 release delayed 1 week, in which itโ€™s announced fonts will be uploaded to the fonts sub-directory of the uploads folder.

Letโ€™s ship the Font Library in WordPress 6.5 contingent on the following, which meet all the criteria and offers a good compromise:

  • The Font Library will use wp-content/fonts as the default storage folder. While locating fonts at the same level as themes and plugins gives fonts a lot of prominence, itโ€™s worth noting 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. themes are heading toward composability, allowing users to change collections of fonts, patterns, templates, and color schemes without switching the full theme. Storing fonts at the same level as themes is the first step to breaking down themes in these composable pieces and establishing new first-class concepts and objects within our software.
  • For installations that donโ€™t support modification of the wp-content directory, the Font Library will use wp-content/uploads/fonts as a fallback location, ensuring we stay true to our project philosophy of designing for the majority while still making the feature available to anyone out of the box without extra steps from the user.ย 
  • The wp_get_font_dir()โ€ƒ(source) is available to return the location of the siteโ€™s fonts folder. Extenders should use this function as it will allow them to seamlessly integrate with the Font Library regardless of their installed version of WordPress. This allows WordPress to manage the preferred directory location and any factors related to migrating folder locations (e.g., consolidating any remaining installations using wp-content/uploads/fonts to use wp-content/fonts)ย in future versions without extenders also needing to make changes.
  • For very edge cases, a font_dir 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.โ€ƒ(source) still allows overriding the font storage folder.
  • Like wp-content/uploads itself, the fonts directory will not adhere to wp_is_file_mod_allowed / DISALLOW_FILE_MODS to prevent font uploads.
  • The 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. will reflect these changes upon publication.

The following is still to be explored after WP 6.5:

  • A means to move the canonical location of the fonts directory. Should the wp-content directory become writable for a site, a safe path forward should be offered for its owners.
  • Related checks will be added to Site Health.
  • A roadmap will be published outlining where the project components are headed in relation to establishing new first-class concepts outside of previously established paradigms within the software (like breaking down themes into fonts, patterns, templates, etc.). Why was this such an important and impactful decision? And how might it present itself again in the future?

Synced Pattern Overrides

During beta a change was merged that switches how blocks are named and marked as overridable patterns. This is proving to have unforeseen side effects that need further research and testing. Given that we need to focus on the solution outlined above for the Font Library, letโ€™s revert this and try again in WP6.6.

Letโ€™s do it!

While there may still be some disagreement about these decisions, I ask that we all support this fair and reasonable compromise to ensure the release is ready for all to enjoy the Font Library feature that many contributors have worked so hard on over the last few years. Sticking to our philosophies is important, but we must balance that with releasing early and often. Weโ€™re not perfect, and the only way to know how is to release features for all to use.

Props to @priethor, @desrosj, @swissspidy, @cbringmann, @dd32, @youknowriad

#6-5

Summary, Dev Chat, March 6, 2024

Start of the meeting in 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/, facilitated by @mikachan.

Announcements

WordPress 6.5 RC 1ย was released on March 5, 2024. Thanks to everyone involved and those who helped test.

Forthcoming Releases

Nextย 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.: 6.5

There are several important changes to our normal development process during the RCrelease 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). stage. For more, see this post: WordPress 6.5 Release Candidate Phase.

Please continue to test the 6.5 release. See this list ofย key features to test, which was published alongside WP 6.5ย 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.ย 3.

During the meeting, @marybaum confirmed the release team for RC2, scheduled for next Tuesday, March 12, 2024. @akshayar will host, @davidbaumwald will run Mission Control (MC), and @audrasjb will be the committercommitter A developer with commit access. WordPress has five lead developers and four permanent core developers with commit access. Additionally, the project usually has a few guest or component committers - a developer receiving commit access, generally for a single release cycle (sometimes renewed) and/or for a specific component. (with @hellofromtonya as a backup).

Nextย 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/ย release: 17.9

Gutenberg 17.9ย is scheduled for release on March 13 and will includeย these issues.

Discussion

The discussion topic for today centered on: how can we make it easier to follow the decision process of major decisions across the project? This was originally raised by @marybaumย and there is some background discussionย here.

The discussion starts here in Slack. There were no clear next steps identified, but a summary of topics raised include:

  • We could consider having a way to share more regular status updates for primary features in a release in order to surface key decisions, request feedback, get more visibility of concerns raised, etc.
  • When key decisions need to be made, how can we ensure the context is easily accessible?
  • We should be careful about not adding more noise to the CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. Team blogblog (versus network, site) during an already busy release period.
  • When key decisions are made, they should be documented in an appropriate place that is easy to reference (e.g., 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 by the repository owner. https://github.com/, TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress., Core Team blog, etc.)

Highlighted posts

The full list of posts from the last week in Core can be read on the agenda at this link.

Open floor

Due to time, we did not have time for open floor this week.

Props to @mikachan for reviewing.

#6-5, #dev-chat, #summary

A Week in Core โ€“ March 4, 2024

Welcome back to a new issue ofย Week inย CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.. Letโ€™s take a look at what changed onย TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.ย between February 26 and March 4, 2024.

  • 49 commits
  • 70 contributors
  • 54 tickets created
  • 9 tickets reopened
  • 102 tickets closed

Ticketticket Created for both bug reports and feature development on the bug tracker.ย numbers are based on theย Trac timeline for the period above. The following is a summary of commits, organized by component and/or focus.

Code changes

Build/Test Tools

  • Add initial tests for the WP_Filesystem_Directclass โ€“ #57774
  • Fix the precommit:emojiscript โ€“ #60520, #57600
  • Update 3rd-party 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 by the repository owner. https://github.com/ Actions โ€“ #59805
  • Use a consistent parameter name between rand_str()and rand_long_str()โ€“ #60401
  • Address capitalization and docblockdocblock (phpdoc, xref, inline docs) inconsistencies in some test class names โ€“ #59647
  • Correct capitalization and fix typos in some test class names โ€“ #59647
  • Expand wp_parse_id_list()unit tests โ€“ #60218, #60217, #59647
  • Use assertSame()in 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. revisioning tests โ€“ #59655

Bundled Theme

  • Fix focus outline in Twenty Twenty-Four in the editor โ€“ #60535

Coding Standards

  • Remove some extra trailing spaces โ€“ #60021
  • Apply some changes after composer formatโ€“ #60233, #60506, #60524

Customize

  • 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): Label menu subitems when updating menus โ€“ #32728

Docs

  • Add missing @globalmention in wp_interactivity()โ€“ #60677, #59651
  • Correct the placement of @globaltags in wp-includes/admin-bar.phpโ€“ #60021
  • Document some globals in wp-admin/setup-config.phpโ€“ #60021
  • Document some globals in wp-settings.phpโ€“ #60021
  • Document the $postglobal in comment feed templates โ€“ #60021
  • Document the $xmlrpc_loggingglobal in logIO()โ€“ #60021
  • Document the usage of $_paused_pluginsand $_paused_themesglobals โ€“ #60021
  • Improve docblock for WP_Block_Patterns_Registry::registerโ€“ #59532
  • Update WP_Query::tax_querydocblock to reflect that the property can be nullโ€“ #60563

Editor

  • Prevent infinite loops when filtering the font library folder โ€“ #60652
  • Simplify sanitization code path in WP_Theme_JSONafter [57496] โ€“ #60360
  • Update Packages with the latest 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 for 6.5 RCrelease 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). 1 โ€“ #60315, #60665
  • do not expose protected post meta fields in 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. bindings โ€“ #60651
  • 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.: Rename data_wp_context()to wp_interactivity_data_wp_context()โ€“ #60575
  • Interactivity API: Rename data_wp_context()to wp_interactivity_data_wp_context()โ€“ #60575
  • Interactivity API: Revert [57742] pending a 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/ package update โ€“ #60575

General

  • Revert r57698 for WP_List_Util::pluck() โ€“ #59774
  • Use capital cased singular for Site Icon โ€“ #60686

HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. API

  • Ensure that breadcrumbs are properly retained after seeking โ€“ #58517, #60687
  • HTML API: Remove superfluous type-coercing empty() check

Help/About

  • Add images to the About page โ€“ #60303

I18Ni18n Internationalization, or the act of writing and preparing code to be fully translatable into other languages. Also see localization. Often written with a lowercase i so it is not confused with a lowercase L or the numeral 1. Often an acquired skill.

  • Cast magic MO marker number to integer โ€“ #60678
  • Improve docs for pomo library classes โ€“ #44424

Media

  • Accessibility: Copy attachment properties on site icon crop โ€“ #60524
  • Use consistent spacing for the media toolbar in both grid and list view โ€“ #43904

Plugins

  • Fix an overlap issue with 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. cards dependencies notice โ€“ #60501
  • Improve plugin dependency adminadmin (and super admin) notices โ€“ #60465
  • Improve plugin dependency related error messages โ€“ #60465
  • Plugin Dependencies: Donโ€™t assume API response has a slugproperty โ€“ #60540

Privacy

  • Update default privacy page content to use latest block markup โ€“ #60530

Query

  • Remove leading whitespace from certain database queries โ€“ #56841

Quick/Bulk Edit

  • Ensure the โ€œAllโ€ checkbox is properly toggled in certain scenarios โ€“ #59121

Toolbar

  • Polish design and code combining duplicate profile links โ€“ #43633, #34668

Props

Thanks to the 70 people who contributed to WordPress Core on Trac: @swissspidy (18), @sabernhardt (10), @costdev (8), @shailu25 (4), @upadalavipul (4), @huzaifaalmesbah (4), @joedolson (4), @youknowriad (4), @audrasjb (3), @afragen (3), @peterwilsoncc (3), @gziolo (3), @viralsampat (3), @afercia (3), @mukesh27 (3), @euthelup (2), @desrosj (2), @wildworks (2), @subrataemfluence (2), @cbravobernal (2), @ankitmaru (2), @westonruter (2), @luisherranz (2), @darerodz (2), @rcreators (2), @mmaattiiaass (2), @spacedmonkey (2), @ironprogrammer (2), @oglekler (2), @knutsp (1), @jonsurrell (1), @benjamin_zekavica (1), @richtabor (1), @laurlittle (1), @johnbillion (1), @seusmaniqbal (1), @ianbelanger (1), @pooja1210 (1), @sumitbagthariya16 (1), @devmuhib (1), @tmatsuur (1), @manooweb (1), @get_dave (1), @talldanwp (1), @kraftbj (1), @jorbin (1), @santosguillamot (1), @xknown (1), @wpfed (1), @tadamarketing (1), @harsh175 (1), @designsimply (1), @celloexpressions (1), @kushang78 (1), @hiteshtalpada (1), @webcommsat (1), @ugyensupport (1), @chaion07 (1), @Toru (1), @254volkan (1), @poena (1), @pbearne (1), @SergeyBiryukov (1), @pbiron (1), @pento (1), @hrshahin (1), @dd32 (1), @jamescollins (1), @thekt12 (1), and @joemcgill (1).

Congrats and welcome to our 5 new contributors of the week: @rcreators, @seusmaniqbal, @tadamarketing, @kushang78, @hiteshtalpada โ™ฅ๏ธ

Core committers: @swissspidy (12), @sergeybiryukov (11), @audrasjb (6), @desrosj (5), @joedolson (3), @youknowriad (3), @dmsnell (2), @davidbaumwald (1), @ryelle (1), @jorbin (1), @antpb (1), @costdev (1), @hellofromtonya (1), and @joemcgill (1).

#6-5, #core, #week-in-core

New Feature: The Block Bindings API

WordPress 6.5 is introducing a new way of extending blocks that substantially reduces the custom code needed to integrate different kinds of data in 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.

This can now be done through the new Block Bindings 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..

What is the Block Bindings API?

Given a coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. block, rather than displaying a userโ€™s inline written content inside of it, imagine wanting to populate that block with data from a particular source instead. For example, the post metadata or custom PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher logic. What would be the process for doing that?

Screenshot showing a heading and paragraph in the Gutenberg editor, with a large red arrow pointing to the paragraph. The paragraph reads: "How would you replace this sentence with data from somewhere else?"

This is actually a trick question: In previous versions of WordPress, you were unable to do this with 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/โ€™s core blocks โ€” it would instead require creating a custom block with particular logic for reading from the source in question. But this is no longer the case.

With the Block Bindings API, you can now bind core blocks to read from different sources without needing to write custom block boilerplate โ€” this means it is possible to bind a Paragraph to read from a postโ€™s metadata, or a Heading to read from a 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.โ€™s PHP logic, all without needing to deal with ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org, block registration, and other particulars of writing custom blocks from scratch for each new source you want to read from.

This initial release of the Block Bindings API in WordPress 6.5 is a big step towards simplifying the process of extending the editor and expanding the capabilitiescapability Aย capabilityย is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on theirย role. For example, users who have the Author role usually have permission to edit their own posts (the โ€œedit_postsโ€ capability), but not permission to edit other usersโ€™ posts (the โ€œedit_others_postsโ€ capability). of blocks. Under the hood, the API already powers a showcase feature being shipped in WordPress 6.5 alongside it: Connecting core blocks to custom fields in the post metadata.

Using the same functionality, as an advanced use case, it is also possible to define and have blocks read from custom sources โ€” more on that briefly below.

Note: For a more detailed walkthrough on creating and using Block Bindings than can be related in this brief 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., see the Introducing Block Bindings tutorial from the WordPress Developer Blogblog (versus network, site).

How do block bindings work?

Overview

Before getting into the rich functionality Block Bindings can enable via custom sources, this section will first review how the API works in general, then detail how to bind core blocks to custom fields in the post metadata.

The following table shows the current compatible blocks and attributes that can be bound:ย 

Supported BlocksSupported Attributes
Imageurl, alt, title
Paragraphcontent
Headingcontent
Buttonurl, text, linkTarget, rel

While the list of compatibility is short for now, this already enables a wide range of use cases, and support for the rest of the core blocks, as well as custom blocks, is planned for the future.

To use Block Bindings, you would specify that these attributes should be read from particular registered sources using the block markup; the logic for those sources would then be executed when rendering on the frontend.

Upon being bound, editing of the attribute in question will be locked and indicators will appear in the editor to signal that the binding has been created.

Screenshot of the Gutenberg editor; a paragraph is selected and there are icons in the block toolbar, as well as a purple outline around the paragraph, declaring the block as bound.

Specifically, here is how to make use of this via the built-in custom fields support.

Custom fields

Importantly, in this first version of the Block Bindings API, there is no UIUI User interface for binding attributes to custom fields yet. Therefore, it is necessary to add the markup manually using the Code Editor in Gutenberg.

To bind a supported attribute to a 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. in the post metadata, you would use markup such as the following:

<!-- wp:paragraph {
"metadata":{
"bindings":{
"content":{
"source":"core/post-meta",
"args":{
"key":"book-genre"
}
}
}
}
} -->
<p></p>
<!-- /wp:paragraph -->

In order for this to work, you would need to make sure the field is registered to the post metadata by including code such as the following in the themeโ€™s functions.php or a plugin.

register_meta(
'post',
'book-genre',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'default' => 'Default text field',
)
);

*Note that the show_in_rest property must be set to true for the time being due to security considerations, though there are plans to explore how to remove this requirement in the future.

Future sources

Support for post metadata is just a start, and the plan is to add more built-in sources, such as site, user, and taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. data, for WordPress 6.6.

That being said, the Block Bindings API already has the functionality to allow for registering of custom sources as well, which is the same functionality used internally to register the core/post-meta source above.

Registering a custom source

Overview

To register a Block Bindings source, one needs to use the register_block_bindings_source() function, which has the following signature:

register_block_bindings_source(
string $source_name,
array $source_properties
);

There are two available parameters:

  • $source_name: A unique name for the custom binding source in the form of namespace/slug. The namespace is required.
  • $source_properties: An array of properties to define the binding source:
    • label: An internationalized text string to represent the binding source. Note: this is not currently shown anywhere in the UI.
    • get_value_callback: A PHP callable (function, closure, etc.) that is called when a blockโ€™s bound attribute source matches the $source_name parameter.
    • uses_context: (Optional) Extends the block instance with an array of contexts if needed for the callback. For example, to use the current post ID, it should be set to [ 'postId' ].

When WordPress encounters the custom bindings source while parsing a block, it will run the get_value_callback function, whose signature should look like this:

projectslug_bindings_callback(
array $source_args,
WP_Block $block_instance,
string $attribute_name
);

It can accept up to three parameters, though you donโ€™t need to include them unless your logic requires them:

  • $source_args: An array of arguments passed via the metadata.bindings.$attribute.args property from the block.
  • $block_instance: The current instance of the block the binding is connected to as a WP_Block object.
  • $attribute_name: The current attribute set via the metadata.bindings.$attribute property key on the block.

Using the Registration Mechanism

In practice, here is how you might use the above registration function to create a simple binding for copyright information:

add_action( 'init', 'projectslug_register_block_bindings' );

function projectslug_register_block_bindings() {
register_block_bindings_source( 'projectslug/copyright', array(
'label' => __( 'Copyright', 'projectslug' ),
'get_value_callback' => 'projectslug_copyright_binding'
) );
}

function projectslug_copyright_binding() {
return '&copy; ' . date( 'Y' );
}

And here is how you would bind a paragraph to the copyright source in the block markup, and how it would look on the frontend:

<!-- wp:paragraph {
"metadata":{
"bindings":{
"content":{
"source":"projectslug/copyright"
}
}
}
} -->
<p>Copyright Block</p>
<!-- /wp:paragraph -->
A screenshot of a post titled "Block Bindings Copyright Example"; in the content is a copyright symbol and the year 2024.

Of course, this is a simple example, and you could make use of the other parameters in the callback signature to create more extensive logic.

Additional API functions

Additionally, there are a few other functions currently part of the public API:

  • unregister_block_bindings_source( $string source_name ): Unregisters a source
  • get_all_registered_block_bindings_sources(): Gets all registered sources
  • get_block_bindings_source( $string source_name ): Retrieves a registered source

Also, please note that while the core sources use shared APIs in the editor UI, be aware that these editor APIs will remain private for the time being while discussion continues on how to standardize extensions to the UI around this feature.

This means that if you would like to implement a UI to handle your custom fields easily, for now, you will need to create that functionality yourself.

Further learning and next steps

For more inspiration on how to use Block Bindings in your own projects, see the registration logic in block-bindings.php and the built-in core/post-meta source, and take a look at the Introducing Block Bindings tutorial series.

With that in mind, Block Bindings are just getting started, and future plans include:

  • Add the possibility of editing the value of the 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. fields directly from the UI.
  • Add UI to allow users to add bindings through the Editor.
  • Create new built-in sources: Site data, post data, and taxonomy data.
  • Add support for more core blocks.
  • Add the ability for developers to extend the Editor UI.

As always, feedback is more than welcome, and we invite you to share your ideas and use cases on Github, this post, or 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/ to help shape the development of the Block Bindings API.

A big thanks to @greenshady for providing code snippets and the initial ideas for this post, as well as @santosguillamot, and @czapla for offering their feedback.

#6-5, #block-bindings, #dev-notes, #dev-notes-6-5

Agenda, Dev Chat, Wednesday March 6, 2024

The next WordPress Developers Chat will take place onย  Wednesday March 6, 2024 at 20:00 UTC in theย coreย channel onย Make WordPress Slack.

The live meeting will focus on the discussion of proposals and releases, updates on 6.5, and have an open floor section.

Additional items will be referred to in the various curated agenda sections, as below. If you haveย ticketticket Created for both bug reports and feature development on the bug tracker.ย requests for help, please do continue to post details in the comments section at the end of this agenda.

Announcements

WordPress 6.5 RC 1 was released on March 5, 2024. Thanks to everyone involved and those who helped test.

Forthcoming releases

Next 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.: 6.5

Updates from the release squad can be shared in the Dev Chat.

Please continue to test the 6.5 release. See this list of key features to test, which was published alongside WP 6.5 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. 3.

Next 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/ release: 17.9

Gutenberg 17.9 is scheduled for release on March 13 and will include these issues.

Discussions

This week the discussion will focus on any priority topics that need to be raised before the next RCrelease 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). for WordPress 6.5.

Proposed topics

  • Are there any priority topics needed for discussion ahead of WordPress 6.5 RC 2?
  • How can we make it easier to follow the decision process of major decisions across the project?
  • Should we reduce the number of leads on a release squad?

Feel free to suggest additional topics related to this release in the comments.

Highlighted posts

CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. Editor Updates

Props to @annezazu for helping to collate this list.

Tickets for assistance

Tickets for 6.5 will be prioritized.
Please include detail of tickets / PR and the links into comments, and if you intend to be available during the meeting if there are any questions or will be async.

Open floor

Items for this can be shared in the comments.

#6-5, #agenda, #dev-chat

Introducing Plugin Dependencies in WordPress 6.5

Overview

#22316 introduces 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. Dependencies to WordPress.

Extensibility of WordPress through plugins and the 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. 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 one of its most beneficial features. There are many plugins that act purely as extensions of others, building functionality on top. The Plugin Dependencies feature aims to make the process of installing and activating addons (dependents) and the plugins they rely on (dependencies) consistent and easy.

New Plugin HeaderHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitorโ€™s opinion about your content and you/ your organizationโ€™s brand. It may also look different on different screen sizes.

A new Requires Plugins header has been introduced.

This must contain a comma-separated list of 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/-formatted slugs for its dependencies, such as my-plugin (my-plugin/my-plugin.php is not supported). It does not support commas in plugin slugs.

How to use the new header

/**
* Plugin Name: Express Payment Gateway Checkout for Shop
* Requires Plugins: shop, payment-gateway
ย */

Requirements

Dependent plugins

The following requirements are placed on dependent plugins:

  • Cannot be installed until its dependencies are installed.
  • Cannot be activated until its dependencies are activated.

Dependency plugins

The following requirements are placed on dependency plugins:

  • Cannot be deactivated while its dependents are activated.
  • Cannot be deleted while its dependents are installed.

What happens if a dependency is no longer met?

If a dependency plugin is deleted via FTPFTP FTP is an acronym for File Transfer Protocol which is a way of moving computer files from one computer to another via the Internet. You can use software, known as a FTP client, to upload files to a server for a WordPress website. https://codex.wordpress.org/FTP_Clients or deployment, a notice will be displayed on the administrationโ€™s plugin screens, informing the user that there are missing dependencies to install and/or activate. Additionally, each dependent whose dependencies are no longer met will have an error notice in their plugin row.

What happens if a plugin update has a new dependency?

The update will be allowed for now, and the dependent will remain active. A notice will be displayed on the administrationโ€™s plugin screens, informing the user that there are missing dependencies to install and/or activate.

What happens if there are circular dependencies?

A circular dependency is when two or more plugins form a 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 in their requirements.

For example: Plugin A requires Plugin B requires Plugin C requires Plugin A

Plugin Dependencies includes circular dependency detection, and will display a notice to inform users of plugins whose requirements are 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.. The plugins cannot be activated, and users should contact the plugin authors so that this circular reference can be broken where appropriate.

Is defensive coding still needed?

Yes. Plugin Dependencies makes it easier for the user to install and activate required plugins, and informs them when these are not met. This means plugin authors can safely remove checks and notices when their dependencies are not installed or activated.

However, at this time, Plugin Dependencies does not include minimum or maximum version support for dependencies, nor does it account for the loading order of plugins. Plugin authors should therefore continue to use function|class|interface_exists() and version checks where their plugin relies on specific functionality being available at a given time.

Does Plugin Dependencies affect WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/?

Plugin Dependencies does not prevent the installation of dependent plugins without their dependencies via WP-CLI, as it is assumed that those using WP-CLI are advanced users that are aware of their dependency stack. However, to avoid missing dependencies going unnoticed, dependent plugins cannot be activated using WP-CLI until their dependencies are activated.

This affects wp plugin activate --all, which may need to be run multiple times if a dependent appears alphabetically earlier than its dependencies. We plan to collaborate with WP-CLI maintainers on possible ways of easing this burden by exploring loading order in WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., WP-CLI, or both, if appropriate.

Limitations

Plugins hosted on WordPress.org

Dependent plugins hosted on WordPress.org can only declare dependencies that are also hosted on WordPress.org. If your plugin hosted on WordPress.org requires plugins that are not hosted there, it is recommended that you do not use the Requires Plugins header in your plugin at this time.

Plugins not hosted on WordPress.org

Dependent plugins not hosted on WordPress.org can declare dependencies whether hosted on WordPress.org or elsewhere. However, the UIUI User interface will not provide an installation link for the third-party dependencies, and these must continue to be installed manually by the user.

Must-Use plugins as dependencies

Must-Use plugins as dependencies are not officially supported by WordPress Core at this time. Discussion will continue in #60504 and we will release further information when decisions about possible future support have been made.

Themes that require plugins

Themes that require plugins are not supported by Plugin Dependencies at this time, and theme authors should continue to use the checks and messaging that they have in place.

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.

The wp_plugin_dependencies_slug filter hook has been introduced to allow for alterations to dependency slugs. For example, if a dependent plugin declares my-plugin as a dependency, and a premium version of my-plugin exists, the premium version can filter the slug and convert it to my-plugin-pro so that it can be detected by Plugin Dependencies.

  • Parameters
    string $slug โ€“ The slug.

Example usage

add_filter( 'wp_plugin_dependencies_slug', 'convert_myplugin_to_myplugin_pro' );

function convert_myplugin_to_myplugin_pro( $slug ) {
if ( 'my-plugin' === $slug ) {
$slug = 'my-plugin-pro';
}
return $slug;
}

UI Changes

Plugins > Installed plugins

The following changes are made:

  • Dependent plugin rows now contain a list of their dependencies, linked to the respective plugin modal to install and activate the dependency.
  • Dependency plugin rows now contain a list of their dependents.
  • If a plugin has dependencies that are not installed and active, the Activate link is disabled.
  • If a plugin has dependents that are active, the Deactivate and Delete links are disabled.
  • Bulk Actions are disabled for dependency plugins.

Before

Three plugin rows, with one plugin requiring the other two. However, there is no indication or enforcement of the requirements.
No dependents or dependencies are listed.

After

Three plugin rows, with one plugin requiring the other two. The requirements are listed under "Requires" and "Required by" sections. The Bulk Actions checkbox is disabled, as well as the Activate, Deactivate, or Delete actions, depending on the status of the plugins.
Dependents and dependencies are listed, and actions are enabled/disabled based on the status of requirements.

Plugins > Add New

The following changes are made:

  • If a plugin has unmet dependencies, the Install Now and Activate buttons are disabled, both in their plugin card and their plugin information modal.
  • Dependent plugin cards now contain a notice listing their dependencies, with a More Details link to the dependencyโ€™s information modal which contains Install Now or Activate buttons based on their current installation status.
  • Plugin information modals are now persistent after button clicks, and modal-based plugin installation and activation are now performed through AJAX directly within the modal.

Before

Plugin card with no dependencies listed and an active Install Now button despite unmet dependencies.

After

Plugin card with dependencies listed with modal links to install and activate each dependency, and the Install Now button disabled while dependencies are unmet.

Onboarding experiences

Due to the unified AJAX approach now used on the Plugins > Add New screen, activation of a plugin will no longer automatically redirect to the Plugins > Installed plugins screen, or to onboarding experiences implemented by plugin authors. This allows users to install and activate multiple plugins without leaving their current context.

Plugins with onboarding experiences usually incorporate checks so that if, for example, their plugin is installed and activated using WP-CLI, the onboarding experience will be triggered when the user enters one of the pluginโ€™s settings screens. Such implementations will be unaffected by Plugin Dependencies, as will activation from the Plugins > Installed plugins screen Activate link.

New WP_Plugin_Dependencies Class

A new WP_Plugin_Dependencies class has been introduced.

The following public API methods are available:

static ::initialize()
Initializes Plugin Dependencies by reading dependencies from the Requires Plugins header, and fetching Plugins API data for dependencies. This runs only once per execution.

static ::has_dependents( $plugin_file )
Determines whether the plugin has plugins that depend on it.

  • Parameters
    string $plugin_file โ€“ The plugin file, relative to the plugins directory.
  • Return value
    bool Whether the plugin has plugins that depend on it.

static ::has_dependencies( $plugin_file )
Determines whether the plugin has plugin dependencies.

  • Parameters
    string $plugin_file โ€“ The plugin file, relative to the plugins directory.
  • Return value
    bool Whether the plugin has plugin dependencies.

static ::has_active_dependents( $plugin_file )
Determines whether the plugin has active dependents.

  • Parameters
    string $plugin_file โ€“ The plugin file, relative to the plugins directory.
  • Return value
    bool Whether the plugin has active dependents.

static ::get_dependents( $slug )
Gets filepaths of plugins that require the dependency.

  • Parameters
    string $slug โ€“ The dependencyโ€™s slug.
  • Return value
    array An array of dependent plugin filepaths, relative to the plugins directory.

static ::get_dependencies( $plugin_file )
Gets the slugs of plugins that the dependent requires.

  • Parameters
    string $plugin_file โ€“ The dependent pluginโ€™s filepath, relative to the plugins directory.
  • Return value
    array An array of dependency plugin slugs.

static ::get_dependent_filepath( $slug )
Gets a dependent pluginโ€™s filepath.

  • Parameters
    string $slug โ€“ The dependent pluginโ€™s slug.
  • Return value
    string|false The dependent pluginโ€™s filepath, relative to the plugins directory, or false if the plugin has no dependencies.

static ::get_dependency_filepath( $slug )
Gets the filepath for a dependency, relative to the pluginโ€™s directory.

  • Parameters
    string $slug โ€“ The dependencyโ€™s slug.
  • Return value
    string|false If installed, the dependencyโ€™s filepath relative to the plugins directory, otherwise false.

static ::has_unmet_dependencies( $plugin_file )
Determines whether the plugin has unmet dependencies.

  • Parameters
    string $plugin_file โ€“ The pluginโ€™s filepath, relative to the plugins directory.
  • Return value
    bool Whether the plugin has unmet dependencies.

static ::has_circular_dependency( $plugin_file )
Determines whether the plugin has a circular dependency.

  • Parameters
    string $plugin_file โ€“ The pluginโ€™s filepath, relative to the plugins directory.
  • Return value
    bool Whether the plugin has a circular dependency.

static ::get_dependent_names( $plugin_file )
Gets the names of plugins that require the plugin.

  • Parameters
    string $plugin_file โ€“ The pluginโ€™s filepath, relative to the plugins directory.
  • Return value
    array An array of dependent names.

static ::get_dependency_names( $plugin_file )
Gets the names of plugins required by the plugin.

  • Parameters
    string $plugin_file โ€“ The dependent pluginโ€™s filepath, relative to the plugins directory.
  • Return value
    array An array of dependency names.

static ::get_dependency_data( $slug )
Returns API data for the dependency.

  • Parameters
    string $slug โ€“ The dependencyโ€™s slug.
  • Return value
    array|false The dependencyโ€™s API data on success, otherwise false.

FAQs

Where can I stay updated on the future development of Plugin Dependencies?

The Plugin Dependencies feature plugin will no longer receive updates now that the Plugin Dependencies feature has been merged into WordPress Core. The feature will be primarily maintained by contributors to the Upgrade/Install and Plugins components. You can stay updated on Plugin Dependencies and other developments by subscribing to the blog.

How can I get involved in the future development of Plugin Dependencies?

You can join us in the #core-upgrade-install channel on Slack. Our weekly meetings are held every Wednesday at 18:00 UTC. Tickets will be opened on WordPress Core Trac.

How can I report an issue?

You can search for an existing ticket or create a new ticket with the type of defect (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.) on WordPress Core TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress..

How can I request an enhancementenhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature.?

You can search for an existing ticket or create a new ticket with the type of enhancement on WordPress Core Trac.

Props to @afragen and @swissspidy for technical review, and @stevenlinx for copy review.

In memory of Alex Mills and Alex King.
WordPress Remembers.

#6-5, #dev-notes, #dev-notes-6-5

Unification of the site and post editors in 6.5

In WordPress 6.5, the site editor has been refactored to match the post editor UIUI User interface and behavior closely.ย 

Preferencesย 

The preferences have been unified between the post and site editor. For instance, if a user enables the top toolbar in the post editor, it will be honored in the site editor and vice versa.ย 

This means that the following preferences have been moved from the core/edit-post or core/edit-site scopes into the core scope.

  • allowRightClickOverrides
  • distractionFree
  • editorMode
  • fixedToolbar
  • focusMode
  • hiddenBlockTypes
  • inactivePanels
  • keepCaretInsideBlock
  • mostUsedBlocks
  • openPanels
  • showBlockBreadcrumbs
  • showIconLabels
  • showListViewByDefault

Accessing the preferences using the previous scope will continue to work but itโ€™s deprecated, you can now access and modify these preferences using:

const isFixedToolbar = window.wp.data.select( 'core/preferences' ).get( 'core', 'fixedToolbar' );
window.wp.data.dispatch( 'core/preferences' ).get( 'core', 'fixedToolbar', true );

Actions and selectors

For the same reasons, the following selectors and actions from โ€˜edit-postโ€™ store to the โ€˜editorโ€™ store:

  • setIsInserterOpened
  • setIsListViewOpened
  • isInserterOpened
  • isListViewOpened
  • isEditorPanelEnabled
  • isEditorPanelOpened
  • isEditorPanelRemoved
  • removeEditorPanel
  • toggleEditorPanelEnabled
  • toggleEditorPanelOpened
const isInserterOpened = window.wp.data.select( 'core/editor' ).isInserterOpened();

Editor Store

The site editor now relies on the editor package, thie means that in order to retrieve the currently edited post or entity, you can use the editor store selectors:

const editedPostType = wp.data.select( 'core/editor' ).getCurrentPostType();
const editedPostId = wp.data.select( 'core/editor' ).getCurrentPostId();

The rest of the editor store selectors and actions should also be now usable within the site editor.

Props to @audrasjb for the technical review and @leonnugraha for the copy review

#6-5, #dev-notes, #dev-notes-6-5

Updates to the HTML API in 6.5

WordPress 6.5 brings significant updates to 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.. Notably, the Tag Processor received a major overhaul allowing it to scan every token in an HTML document and unlocking a broad array of new functionality. The HTML Processor supports much more of the HTML specification than it did when it was minimally introduced in WordPress 6.4.

New functionality in the Tag Processor.

The Tag Processor was designed to scan every 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.) in an HTML document, skipping all of the non-tag tokens. In WordPress 6.5 it can scan everything. Tokens are the fundamental pieces that make up a document; in the case of HTML, they are the tags, comments, doctype definitions, and text nodes. This means that itโ€™s now possible to read the text content of an HTML document, trivializing previously-complicated operations like stripping tags or truncating HTML.

Supporting this work is the introduction of a new concept called modifiable text. Modifiable text represents content within token boundaries, or content which can be changed without affecting the structure of the document as a whole. Different tokens contain different types of modifiable text:

  • The entire span of a text node is modifiable text.
  • The inside contents of an HTML comment is modifiable text.
  • The content between the opening and closing tags of special elements is modifiable content.

In this case, special elements refer to elements whose inner contents cannot contain other HTML tags. These include the contents of SCRIPT and STYLE elements as well as the contents of the TITLE and TEXTAREA elements. There are a few more representing deprecated or 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. syntax: see the class documentation for a comprehensive list.

New Methods.

  • next_token() advances to the next token inโ€‚the document, including closing tags. Unlike next_tag() there is no query for this method. It scans everything.
  • get_token_type() indicates what kind of token was found, e.g. a #tag or #text or #comment.
  • get_token_name() returns a value roughly corresponding to the DOM nodeName, e.g. SPAN or #text or html (for doctype declarations).
  • get_modifiable_text() returns the properly-decoded text content for a matched token.
  • get_comment_type() indicates why the token is a comment, since different kinds of invalid markup become HTML comments. For example, <โ€‹![CDAโ€‹TA[โ€‹text]โ€‹]> is an HTML comment of the type COMMENT_AS_CDATA_LOOKALIKE because it appears as though it was intended to be a CDATA section, which doesnโ€™t exist within HTML content.
  • paused_at_incomplete_token() indicates if the Tag Processor reached the end of the document in the middle of a token. For example, it may have been truncated in the middle of a tag.

Example usage:

$title = null;
$text_content = '';
$processor = new WP_HTML_Tag_Processor( $html );
while ( $processor->next_token() ) {
    if ( '#text' === $processor->get_token_type() ) {
        $text_content .= $processor->get_modifiable_text();
    } elseif ( null === $title && 'TITLE' === $processor->get_token_name() ) {
        $title = $processor->get_modifiable_text();
    }
}

echo $title ? $title : '(untitled post)';
echo "\n\n";
echo $text_content;

Expanded support in the HTML Processor.

WordPress is now able to recognize and properly parse most HTML. There are only a few major exceptions.

  • The HTML Processor will bail any time it encounters a FORM, MATH, SVG, TABLE, or TEMPLATE tag. These elements introduce complicated parsing rules that require additional care, testing, and design work.
  • There are times when an HTML parser needs to implicitly create an element that wasnโ€™t in the HTML itself, or when it needs to move a tag to an earlier place in the document. This requires further design work to properly communicate that the document has retroactively changed.
  • If the HTML Processor is fed full HTML documents or snippets that exist outside of a BODY element (e.g. a document HEAD), then it will abort, as it currently only supports parsing HTML inside a BODY context.

The last point highlights that the HTML Processor has been developed following the needs of 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.-related code and focused on rules in the HTML specification relating to how tags ought to be interpreted inside a BODY element. Once this section is complete, the others will be added. Thankfully, this is the hardest section by a long shot, and parsing full documents should follow quickly after the primary work is done.

Notes for experimenters.

If youโ€™ve been experimenting with the HTML API and building custom subclasses of the Tag Processor then itโ€™s important to understand two changes: handling of incomplete documents, and special HTML tags with modifiable text.

Incomplete documents.

Previously, when the Tag Processor reached the end of a document and there was an incomplete token (for instance, โ€œ<div clโ€œ), it would return false and finish parsing the document. Now that the Tag Processor can scan and visit every token in the document, however, it will indicate if it encountered such a situation. When it does, it will still return false, but it will back up to the beginning of the token and freeze. In a future release, it will be possible to extend the document and continue processing. For now, if paused_at_incomplete_token() returns true, then you can know that there might have been more to the original HTML that was sent into the processor than it received.

Special HTML tags with modifiable text.

The HTML Processor properly tracks document structure and is the appropriate method for determining when an element starts and ends. Many simpler approaches will often seem correct enough for practical use, but these will all break down in common situations. While the Tag Processor makes it easier to estimate structure than regex-based approaches, be cautioned whenever skipping the rules that the HTML Processor implements, as even normative HTML often breaks simple mental models for translating HTML text into DOM structure.

For those who are relying on the Tag Processor to estimate structure, thereโ€™s a change in behavior that might break your subclasses: the Tag Processor no longer visits the closing tag for the group of special elements. These are tags like SCRIPT, STYLE, and TITLE. The reason for this change is that these elements cannot contain other tags inside of them. It will often look like they do (for instance, with <title>an <img> is plain text</title>), but the inner content is parsed as text and not as HTML. This change prevents misinterpreting those inner contents as HTML tags.

When the Tag Processor encounters a SCRIPT tag or any of these special elements, it will continue parsing until it finds the associated closing tag and then the inner contents will be available as modifiable text. For algorithms tracking depth in a document, they will not only need to check if the tag is_void(), but also if itโ€™s a special element since the closing tag will no longer be separately visited.

Note that itโ€™s still possible to visit a closing tag for a special element, but only if they are unexpected and come without a corresponding opening tag.


Follow along in the CoreCore Core is the set of software required to run WordPress. The Core Development Team builds 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/ channel #core-html-api or watch here for updated posts to be part of the conversation driving and developing this API.

Props to @stevenlinx for copy review on this post.

#dev-notes #dev-notes-6-5 #6-5

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 7.4 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="otherPlugin::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