What’s new in Gutenberg 23.7? (05 August)

“What’s new in 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/…” posts (labeled with the #gutenberg-new tag) are posted following every Gutenberg release on a biweekly basis, showcasing new features included in each release. As a reminder, here’s an overview of different ways to keep up with Gutenberg and the Editor.

What’s New In
Gutenberg 23.7?

Gutenberg 23.7 has been released and is available for download!

Version 23.7 includes many improvements over features added with 23.6, with updates to the BlockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. Editor, the new Gallery block’s dynamic mode, user control to enable the Global Styles inheritance UIUI User interface, and a series of smaller visible editor layout fixes.

Various editor improvements

Much of the 23.7 cycle has been focused on smaller visual editor improvements. Floated blocks no longer overlap sticky blocks, the empty block appender now sits in the right place inside blocks that capture their own toolbars, and the Pullquote block finally honors a custom line height in the editor so it matches the front end. Fixed device preview heights are also restored for the mobile and tablet views.

Gallery block dynamic mode improvements

The new Gallery block dynamic mode that shipped in Gutenberg 23.6 had an ambiguous “Convert to images” toolbar button that didn’t describe what it actually did. That button has been renamed to “Detach”, and a modal appears to better explain to the user what happens when detaching images

Other Notable Highlights

  • Global Styles inheritance UI. This experimental feature is now opt-in, and is enabled from the Gutenberg Experiments settings page (#80815).
  • Math block: LaTeX errors stop interrupting you. Parse errors no longer fire on every keystroke — LaTeX input now uses ValidatedTextareaControl, so feedback is deferred until the field first loses focus and the per-keystroke screen reader announcement is gone (#80500).
  • Grouped options across the form primitives. Combobox, Select, and SelectControl gain Group and GroupLabel subcomponents, so grouped options compose consistently across the item-popup families (#80574).

Changelog

Enhancements

  • Base styles: Allow overriding focus ring color in outset-ring__focus. (80587)
  • WidgetWidget A WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user. Dashboard: Measure the 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. fit and document the chrome. (80423)
  • Widget Primitives: Ship as a script module. (80149)

Components

  • Combobox, Select, SelectControl: Add Group and GroupLabel. (80574)
  • DataViews/Font Library: Give search fields a fixed width to stop layout shift. (80315)
  • DataViewsPicker: Add Shift+Click range selection to the picker-table, picker-grid, and picker-activity layouts. (80413)
  • Enhance sandbox component to accept sandbox prop. (69617)
  • Input: Hide native spin controls for type=”number”. (80646)
  • SearchControl: Render the suffix only if there’s one. (80356)
  • UI: Add Autocomplete.Row primitive. (80490)

Block Library

  • Add Table of Contents end-to-end user story coverage. (80199)
  • Math: Use ValidatedTextareaControl for LaTeX input. (80500)

Post Editor

  • Add a responsiveEditingEnabled editor setting to hide the Responsive styles option. (80814)

Font Library

  • Fix navigation page select font size to match DataViews. (80617)

Collaboration

  • RTC: Disable Quick Edit while a post is being edited. (80016)

Global Styles

  • Extract shared preset management from shadows and font sizes. (79810)

Block Editor

  • Reflect inherited Global Styles values in block inspector controls. (77894)

Bug Fixes

  • Block Editor: Fix floated blocks overlapping sticky blocks. (80749)
  • Update view configuration 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. versioning. (80319)
  • View config: Reject shape-mismatched merges, define empty-array semantics, strip nulls from appended members. (80571)
  • createInterpolateElement: Handle unmatched closing tags gracefully. (80618)

Block Library

  • Account for non-lowercase VIDEO 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 render_block_core_video(). (80537)
  • Cover/Accordion: Exit on Enter. (77301)
  • Dynamic Gallery: Rename toolbar button to Detach and add a modal explaining what will happen. (80727)
  • Fix: Pullquote custom line height in the editor. (80586)
  • Gallery: Make dynamic mode conversion a single undo level. (80665)
  • List Block: Preserve ordered type on indent. (75353)
  • Media Editor: Show a loading state while the cropped file loads. (80460)
  • Media: Remove the redundant __heicUploadSupport flag. (80452)
  • Navigation: Fix missing ‘Add block’ option in Link UI when inside template parts. (78427)
  • Playlist: Shorten track toolbar button label. (80759)
  • Query LoopLoop The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop: Add translationtranslation The process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. context to the ‘Offset’ setting label. (80582)
  • Social Link: Fix stray closing tag in Tumblr icon markup. (80257)

Block Editor

  • Background image control: Remove duplicated focus ring. (80671)
  • Block Tools: Fix empty block appender position inside blocks that capture toolbars. (80592)
  • Fix cursor position during forward delete of empty blocks. (77525)
  • Fix preset round-trip test imports after preset utils consolidation. (80589)
  • Global Styles panels: Fix wrong preset committed and shown when two color presets share a hex. (80497)
  • Global Styles: Resolve link element styles in block inspector controls for blocks that are links. (80607)
  • RTC: Prevent controlled block synchronization from intercepting undo. (80503)
  • Rich text: Remove tabIndex from editable elements again to fix shift+click selection. (80651)
  • Writing flow: Extend block selections with shift+arrow when there is no native selection. (80687)
  • Writing flow: Mark shift+click as a multi-selection gesture. (80286)
  • Writing flow: Stop the page scrolling on caret moves within blocks taller than the viewport. (80708)
  • RichText: Don’t apply input transform when there’s no onReplace. (80978)
  • RichText: Fix paste handler crash when pasting files. (81010)

Post Editor

  • Editor: Leave undo to the browser in fields that handle their own undo. (80768)
  • Editor: Restore fixed device preview height for mobile and tablet. (80271)
  • 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. boxes: Match heading styles with Gutenberg panels. (80670)
  • Notes: Capture the target block before saving a block-level note. (80690)
  • Notes: Register the inline note format at import time. (80576)
  • Notes: Report save success consistently from note actions. (80748)
  • Notes: Sync the sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. selection to the inline marker under the caret. (80610)
  • Post Lock: Fix modal flipping to “Someone else has taken over” for a locked-out viewer. (79997)
  • Wrap notices in ThemeProvider with 0 corner radius. (79523)
  • iOSiOS The operating system used on iPhones and iPads.: Remove jumping hack, add typewriter. (74596)

Components

  • DataForm: Stop card and details validation from hijacking focus. (80685)
  • Fix Root .prettierrc.js override issue. (80422)
  • GradientPicker: Select by slug so two presets sharing a gradient keep their identity. (80554)
  • Storybook: Fix Emotion jsxImportSource. (80426)
  • ToolsPanel: Migrate styles to an SCSS Module. (80445)

Client Side Media

  • Fix upload hang when converting long animated GIFs: Decode only the first frame for still outputs. (80260)
  • Media: Stop forcing crossorigin on IMG tags in media templates. (80532)
  • wp-build: Sync the page template preload field list with coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.-data. (80648)

Collaboration

  • Notes: Detach core’s mention kses 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. in the baseline strip test. (80656)
  • RTC: Compact during serialization. (80707)

Media

  • Media REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/: Backportbackport A port is when code from one branch (or trunk) is merged into another branch or trunk. Some changes in WordPress point releases are the result of backporting code from trunk to the release branch. sideload from URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org path upload size check. (80659)

Global Styles

  • Theme JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML.: Level block-level preset class specificity with :Where(). (80657)

Data Layer

  • RTC: Preserve collaborators’ unsaved edits when another user saves. (79936)

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)

Block Library

  • Improve the various Alignment controls props handling. (63696)
  • Navigation: Fixes aria-expanded not updating on hover submenu inside overlay. (77563)

Performance

Block Editor

  • Rich text: Read the contentEditable attribute in ownsSelection to avoid forced layout. (80549)
  • Try to fix typing performance regressionregression A software bug that breaks or degrades something that previously worked. Regressions are often treated as critical bugs or blockers. Recent regressions may be given higher priorities. A "3.6 regression" would be a bug in 3.6 that worked as intended in 3.5.. (80507)

Post Editor

  • Editor: Avoid unnecessary term re-fetches in FlatTermSelector. (80623)

Data Layer

  • Core Data: Move EntitiesSavedState component out of editor (rebase of #71948). (80485)

Experiments

Dashboard

  • Dashboard Widgets: Harden action href sanitization. (80510)
  • Dashboard Widgets: Sanitize help link hrefs. (80409)

Block Editor

  • Global Styles: Put the inheritance UI behind a Gutenberg experiment. (80815)

Documentation

  • Add nvm use instructions to AGENTS.md. (80755)
  • Add progressive-discovery pattern for agent instructions and skills. (80650)
  • Added Missing Global Documentation in table-of-contents/index.php. (80442)
  • Docs: Add missing file-level and class-level docblocks to WP_Icon_Collections_Registry. (80172)
  • Docs: Clarify agent guidance discovery. (80753)
  • Docs: Clarify getBlock behavior with inner block controllers. (80773)
  • Docs: Expand the back-porting to WP Core guide. (80593)
  • Docs: Require view configuration filter callbacks to return the container. (80642)
  • Docs: Update iframeiframe iFrame is an acronym for an inline frame. An iFrame is used inside a webpage to load another HTML document and render it. This HTML document may also contain JavaScript and/or CSS which is loaded at the time when iframe tag is parsed by the user’s browser. guidance for Gutenberg 23.6. (80629)
  • Theme: Update Storybook adminadmin (and super admin) color scheme examples. (80569)
  • UI: Add dialog vs drawer design guidance. (80783)
  • Update documentation for server-side view configuration filters. (80744)
  • Used link for URL in inline documentation. (80716)

Code Quality

  • ESLint: Add missing not-recommended components to denylist. (80754)
  • Fix: Update webpack-dev-server to ^5.2.1 to help with dep alerts. (80347)
  • 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/ workflows: Fix changelog checks for forked PRs. (80538)
  • Interactivity API: Refactor directives into self-registering modules. (79975)
  • RTC: Use array_any() for newer-compaction check in polling sync server. (80522)
  • RTC: Use str_contains() in WP_Sync_Config. (80476)
  • Storybook: Build the resolve specifier as a URL-style string. (80416)
  • Tools: Resolve dependencies independently of the node_modules layout. (80414)

Components

  • Autocomplete: Reference the suggestions list with aria-controls and aria-haspopup. (80403)
  • ExternalLink: Use shared focus ring mixin. (80573)
  • Make useSelectionProps hook layout agnostic. (80677)
  • Migrate Disabled to SCSS module. (80643)
  • Migrate FormTokenField to SCSS module. (80472)
  • Migrate SearchControl to SCSS module. (80474)
  • Packages: Update date-fns to 4.4.0. (80763)
  • Theme: Update Color.js to 0.7.1. (80762)
  • Theme: Update colorjs.io dependency and drop 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. workaround. (80272)
  • UI: Improve component code readability in Storybook by using arrays for children. (80352)
  • theme: Disallow src in published package. (80213)

Block Library

  • Guards against error throwing attribute values. (80558)
  • Make editableRoot a private block setting rather than a public support. (80820)
  • Misc fixes for WordPress-Develop 7.0 merges. (75985)
  • Page List: Use null coalescing operator for parentPageID attribute. (80728)
  • Remove redundant @jest-environment jsdom pragma and lint against it. (80676)
  • Remove unnecessary __next40pxDefaultSize props from form controls. (80540)
  • Table of Contents: Use str_contains() instead of strpos() check. (80418)
  • Tabs : Remove default paragraph from tab-panel template. (80565)

Block Editor

  • Duotone: Dedupe duotone utils into global-styles-engine. (80598)
  • Reduce duplicated preset utility implementations. (80245)
  • Refactor ‘URLInput’ to function component. (80721)

Post Editor

  • Icons: Validate SVG icons include viewBox. (80273)
  • Notes: Cancel in-flight hover highlight when focus leaves a note thread. (80752)

Data Layer

  • Packages: Update memize to 2.1.1. (80764)

Global Styles

  • Rename unit testunit test Code written to test a small piece of code or functionality within a larger application. Everything from themes to WordPress core have a series of unit tests. Also see regression. files and drop .spec.js suffix. (80711)

Site Editor

  • Edit Site: Replace Theme usage in canvas loader with CSSCSS Cascading Style Sheets.. (80688)

Collaboration

  • Move real-time collaboration code to lib/experimental/collaboration. (80469)

Tools

  • Docs: Update the release form screenshot for GitHub’s new Release label UI. (80567)
  • Release: Require a working GitHub CLICLI Command Line Interface. Terminal (Bash) in Mac, Command Prompt in Windows, or WP-CLI for WordPress. for cherry-picking. (80568)

Build Tooling

  • Build: Add independent reactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org-18 vendor package. (80367)
  • Build: Handle project paths containing spaces in dev script. (80519)
  • Components: Skip polymorphism prop typings on intersection. (80364)
  • DependencyExtractionWebpackPlugin: Include extracted styles in the asset version hash. (80601)
  • React 19: Add end-to-end compat test for boolean inert attribute. (80397)
  • Resolve Prettier explicitly for isolated layout. (80529)
  • Storybook: Remove Emotion as JSX import source. (80647)
  • WP Build: Avoid infinite worker build loop. (80361)
  • Improve pre-flight npm access checks. (80334)

Testing

  • Jest: Fix ignore pattern for TypeScript declaration files. (80737)
  • Jest: Update to v30 (breaking). (80767)
  • Only use Flakiness.io in canonical Gutenberg repo. (80816)
  • Perf Tests: Fix ‘Selecting blocks’ metric reporting 0 ms. (80524)
  • RTC: Fix deleted-user test on 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. (80463)
  • Site Editor: Add end-to-end coverage for view configuration extensibility. (80577)

Various

Components

  • Base Styles: Remove accent color parameter from input-control. (80595)
  • Remove private Theme component. (80691)

First-time contributors

The following PRs were merged by first-time contributors:

  • @dilipom13: Meta boxes: Match heading styles with Gutenberg panels. (80670)
  • @faisalahammad: Editor: Restore fixed device preview height for mobile and tablet. (80271)
  • @nickchomey: Interactivity API: Refactor directives into self-registering modules. (79975)

Contributors

The following contributors merged PRs in this release:

@aaronrobertshaw @adamsilverstein @aduth @andrewserong @chriszarate @ciampo @CookieDarb @DarkMatter-999 @desrosj @dhananjaykuber @dilipom13 @dpmehta @ellatrix @enejb @faisalahammad @getdave @himanshupathak95 @i-am-chitti @im3dabasia @Imran92 @jeryj @jorgefilipecosta @jsnajdr @juanfra @Kgupta62 @MaggieCabrera @Mamaduka @manzoorwanijk @maxschmeling @mirka @Mustafabharmal @nickchomey @noruzzamans @ntsekouras @oandregal @obenland @ocean90 @peterwilsoncc @ramonjd @retrofox @scruffian @shail-mehta @shekharnwagh @shimotmk @simison @sirreal @Soean @t-hamano @westonruter @yashjawale

Props to @mamaduka for reviewing.

#block-editor #core-editor #gutenberg #gutenberg-new

WordPress 7.1 Release Candidate Phase

Now that WordPress 7.1 has entered the Release Candidate phase, the following policies are in place.

These policies mainly cover how and when CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. committers can commit. For non-committing contributors, this post may help explain why Core committers make certain decisions.

Committing to Trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision.

In order to not interfere with ongoing efforts to improve github actions, branching has been delayed until early next week. This post will be updated after the branchbranch A directory in Subversion. WordPress uses branches to store the latest development code for each major release (3.9, 4.0, etc.). Branches are then updated with code for any minor releases of that branch. Sometimes, a major version of WordPress and its minor versions are collectively referred to as a "branch", such as "the 4.0 branch". is created.

As a result, all commits to trunk will require double sign-off by two core committers until the 7.1 branch is created.

The dev-feedback keyword should be used to request a second 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.’s review, dev-reviewed should be added to indicate a second committer has reviewed and approved the commit to trunk. Commits to the test suite do not require double sign-off. Only committers should add the dev-feedback and dev-reviewed keywords.

String Freeze

RC1 release marks the hard string freeze point of the release cycle. While this normally means the Polyglots teamPolyglots Team Polyglots Team is a group of multilingual translators who work on translating plugins, themes, documentation, and front-facing marketing copy. https://make.wordpress.org/polyglots/teams/ can begin translating strings from the upcoming release into their local language, a version-specific branch is required. As a result, strings will not be available for translationtranslation The process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. until the 7.1 branch is created.

Despite this, the normal rules for hard string freeze will be followed:

  • No new strings are permitted. Exceptions can be made for critical strings (the About page, for example) provided they are properly tagged with the i18n-change keyword in TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. and the Polyglot team is made aware.
  • Existing strings can be removed and/or duplicated if needed.

Seek guidance from the Polyglots team reps for any strings reported as buggy. A buggy string is one that can not be translated to all languages in its current form. 

Tickets on the WordPress 7.1 milestone

Only two types of tickets may be placed on/remain on the 7.1 milestone:

  • Regressions: bugs that have been introduced during the WordPress 7.1 development cycle, either to existing or new features.
  • Test suite expansion: tests can be committed at any time without regard to code or string freezes. This can cover either new or existing features.

Bumping Trunk to WordPress 7.2-alpha

After the 7.1 branch is created, this post will be updated and a @committers announcement will be made 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/ informing everyone that trunk is open for commits related to the next version of the software.

Props @joedolson for peer review.

#7-1

WordPress 7.1 Field Guide

This guide outlines major developer features and breaking changes in 7.1 and is published during the Release Candidaterelease candidate One of the final stages in the version release cycle, this version signals the potential to be a final release to the public. Also see alpha (beta). phase to help inform WordPress extenders, CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. developers, and everyone else interested in the latest WordPress development.

There are more than 310 Core Trac tickets included in WordPress 7.1, over 100 of which are enhancements and feature requests, and more than 180 bug fixes. This release includes 40+ tickets focused on the Editor, with the most attention going to 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) (46), UIUI User interface (40), and administration (28) focuses. Additionally, this release includes almost 600 enhancements and more than 630 bug fixes, coming from 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/.

A quick search of the diff between 7.0.2 and the current trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision. (7.1-beta4) reveals 20 new 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. (19 filters and 1 action), 1480 total files changed with 88163 insertions and 18601 deletions. Kudos to everyone who contributed to the 7.1 release, in any way, shape, or form.

Below is a breakdown of the most important developer-related changes included in WordPress 7.1.

Media

WordPress 7.1 continues the modernisation of media workflows across the editor, 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/, and Media Library. The release introduces client-side processing capabilitiescapability 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)., improves the handling and registration of image sizes, and changes the default Media Library browsing experience.

Client-side media processing

New client-side media processing APIs allow supported image operations to happen in the browser before a file is uploaded. Related REST API changes support validating image dimensions, selecting size-aware encoding quality, and registering a sideloaded file for multiple image sizes.

Related tickets:

  • #64798 — REST API: Add dimension validation to sideload endpoint
  • #65262 — REST API: expose size-aware encode quality on attachment responses
  • #65481 — REST API: Support registering one sideloaded file under multiple image sizes

Media library

Infinite scrolling is enabled by default in the Media Library grid, with a per-user option to restore the previous pagination behaviour. The release also includes fixes for upload counts, duplicate caption IDs, and other media-management details.

Other media changes:

  • #65053 – Correct the media-upload count when uploading multiple files from the post editor
  • #65315 – Prevent duplicate figcaption IDs when the same image has different captions

Accessibility

WordPress 7.1 includes accessibility improvements across administration screens, list tables, setup flows, widgets, navigation, and editor-related interfaces. The changes improve semantics, keyboard and pointer interaction, focus behaviour, contrast, and the presentation of contextual information.

Administration

Administration improvements make hierarchical relationships and table structure clearer to assistive technologies. They also refine focus behaviour, controls, contrast, and interaction patterns across several screens.

Accessible tooltips in core

WordPress 7.1 introduces a shared mechanism for accessible name and informational tooltips. Core now uses this mechanism in selected interfaces, giving developers a consistent pattern for presenting supplementary information without relying on inaccessible title attributes or pointer-only interactions.

  • #51006 — Add a mechanism for accessible tooltips in core
  • #55343 — Add Tooltip to “Remember Me” (WP Login Form)
  • #50921 — Consider adding tooltips for metaboxMetabox A post metabox is a draggable box shown on the post editing screen. Its purpose is to allow the user to select or enter information in addition to the main post content. This information should be related to the post in some way. order buttons

Other accessibility improvements:

  • #64932 – Make subpage hierarchy in post list tables accessible.
  • #65027 – Add IDs to section titles generated by the Settings 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.
  • #65250 – Correct mouse interaction for the first submenu item when “Collapse Menu” is enabled
  • #65382 – Improve adminadmin (and super admin) colour scheme contrast for the editor chrome.
  • #65454 – Improve accessibility of setup-config.php and install.php
  • #47670 – Fix the accessibility problem caused by multiple RSS widgets
  • Improving visibility, contrast, layout, and overall accessibility in #65419, #65530, #65532, #65630 and more.

Abilities API

WordPress 7.1 builds on the Abilities API introduced in WordPress 6.9, making abilities easier to discover, expose, validate, and integrate with external clients. The release adds filtering to wp_get_abilities(), execution lifecycle hooks, a unified public exposure flag, client-compatible 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. Schema preparation, and several smaller API refinements.

Global styles

WordPress 7.1 expands the styling tools available to 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. and theme developers, with responsive style variations, configurable viewports, additional interaction states, and text-shadow support. These changes give themes and blocks more expressive styling options while keeping their configuration within the Global Styles system.

SVG Icon API

Starting with WordPress 7.1, the SVG Icon API provides a standardised way to register and render custom icons in WordPress.

DataViews, DataForm, and View Config APIs

The DataViews and DataForm APIs continue to mature in WordPress 7.1, alongside new View Config capabilities for controlling Site Editor screens. Developers can use the expanded APIs to customize data-driven interfaces and 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. which views and layouts are available in supported editor contexts.

Editor

WordPress 7.1 includes a broad collection of editor improvements spanning block behaviour, extensibility APIs, interface components, styling tools, and the editing environment itself. The sections below highlight the changes most likely to affect block, theme, and pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party. developers.

New Block Support

WordPress 7.1 adds block support for background gradients and minimum width, allowing blocks to opt into these design controls through their metadata. The release also improves the Custom HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. block by allowing supported blocks to remain editable inside its preview.

Enforced iframed editor

WordPress 7.1 completes the move to an iframeiframe iFrame is an acronym for an inline frame. An iFrame is used inside a webpage to load another HTML document and render it. This HTML document may also contain JavaScript and/or CSS which is loaded at the time when iframe tag is parsed by the user’s browser.-based post editor, including for sites that register legacy 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. boxes. This creates a more consistent editing environment, but plugins that rely on reaching across the editor document boundary should review their JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com and CSSCSS Cascading Style Sheets. for compatibility.

Editor components

The editor component library receives new features, refinements, and API updates in WordPress 7.1. Developers building editor interfaces should review the component changes for new capabilities, updated behaviour, and any migrationMigration Moving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies. considerations.

Design System

WordPress 7.1 introduces a theming foundation for the WordPress Design System. The new approach uses design tokens and shared styles to make interfaces more consistent while giving supported environments a structured way to apply different visual themes.

Persistent Admin Bar

The WordPress toolbar now remains available while navigating supported editor screens, creating a more consistent path between the front end, administration area, Site Editor, and Block Editor. Developers extending the toolbar should review how their items behave across these contexts and during client-side navigation.

External libraries

WordPress 7.1 updates bundled third-party dependencies to improve compatibility, maintenance, and security. The most notable change is the update to jQuery UI 1.14.2, which may require testing for plugins that depend on jQuery UI behaviour or styling.

Other updates

Several developer-facing changes in WordPress 7.1 do not fall under any of the larger feature areas but may still affect existing integrations. These include adjustments to notification filtering and other focused API or behavioural changes.

But wait, there’s more!

7.1 offers so much more! More than 180 Core bugs, over 630 Gutenberg bugs, 100 enhancements and feature requests, and more than 20 blessed tasks have been marked as fixed in WordPress 7.1.

The following highlights call attention to smaller changes that may affect integrations, expected return values, generated markup, compatibility, or established developer workflows:

AI#65504 – AI Client – updates execute_abilities() to mirror has_ability_calls() by checking is_ability_call() before executing, and adds regressionregression A software bug that breaks or degrades something that previously worked. Regressions are often treated as critical bugs or blockers. Recent regressions may be given higher priorities. A "3.6 regression" would be a bug in 3.6 that worked as intended in 3.5. coverage for mixed ability and non-ability calls.

Comments#65392 – “Show more comments” fails for comment types other than comment

Editor and blocks:

  • #64838 – Prevent block pseudo-state styles from being applied to the default state
  • #65039 – Add context to _doing_it_wrong() messages in WP_Block_Type_Registry::register()
  • #65373 – Query LoopLoop The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop block: add an option to exclude the current post

Formatting and compatibility#42517 – Make sure get_file_data() recognises headers prefixed by a <? 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.).

Login, installation, and 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#65506 – Fix incorrect HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. URLs in multisite signup and activation when SSLSSL Secure Sockets Layer. Provides a secure means of sending data over the internet. Used for authenticated and private actions. is enabled

    Privacy

    • #44498 – Run _wp_personal_data_cleanup_requests() on cron
    • #44723 – Return the WP_User_Request user ID as the documented type

    REST API and XML

    • #65536 – XML-RPC: fix the argument mismatch in _multisite_getUsersBlogs
    • #65670 – Prevent WP_REST_Attachments_Controller::get_attachment_filesize() from failing on non-integer metadata

    Themes and templates

    • #42513 – Improve WP_Theme::get_post_templates() performance for large themes
    • #64848 – Prevent implicit coercion in WP_Theme_JSON::to_ruleset()
    • #65049 – Templates: add a date field

    What changes didn’t make the 7.1 release

    Not every feature explored during the release cycle was ultimately included in WordPress 7.1. The following initiatives were deferred, changed direction, or remained experimental, giving contributors more time to validate their design and implementation before they reach Core.

    … as sometimes what we don’t add is more valuable than what we do.

    Anne McCarthy in #7-1-release-leads

    Classic block

    An initial proposal would have hidden the Classic block from the inserter for new content while preserving existing instances. After further discussion and testing, the change was reverted, so the Classic block remains available in WordPress 7.1.

    The ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org 19 upgrade was also deferred beyond WordPress 7.1 and continues as an experiment in the Gutenberg plugin.

    Real-time collaboration

    Real-time collaborative editing received extensive testing and feedback during the WordPress 7.1 cycle, but it is not enabled in the final release. Work continues on the editing experience, conflictconflict A conflict occurs when a patch changes code that was modified after the patch was created. These patches are considered stale, and will require a refresh of the changes before it can be applied, or the conflicts will need to be resolved. handling, compatibility, and the path toward a future Core integration.

    “On This Day” widgetWidget A WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user.

    The proposed “On This Day” dashboard widget was considered during the WordPress 7.1 cycle but was not included in the release. Further work and discussion can continue in the associated TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #65801.

    Merge proposals

    Several projects presented merge proposals during the WordPress 7.1 cycle. Some related foundations were included in the release, while the broader proposals continue to evolve and may be considered again after further testing, documentation, and feedback.

    Thank you to everyone who contributed to this version of WordPress, whether through code, testing, or something else – your contributions matter and help Make WordPress.

    Props to @joedolson and @benjamin_zekavica for collaboration and review.

    #7-1, #field-guide

    The notify_post_author filter now has the final say on post author notifications

    WordPress 7.1 changes when wp_new_comment_notify_postauthor() checks a comment’s approval status: the check now happens before the notify_post_author 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. is applied, rather than after. As a result, the filter receives an accurate default value, and its return value fully determines whether a notification is sent. See #64217.

    Previous behavior

    The filter received a default derived only from the comments_notify option (or the wp_notes_notify option for notes). The comment’s approval status was checked after the filter ran, which had two consequences:

    1. The filter received a misleading default of true for unapproved comments whenever the option was enabled, even though no notification would be sent.
    2. Returning true from the filter could not force a notification for an unapproved comment – the return value was silently discarded.

    New behavior in 7.1

    The approval status is now incorporated into the default value passed to the filter, and the filter’s return value is final:

    • The default is false for comments that are not approved, including those held in moderation, marked as spam, or trashed.
    • The default for approved comments continues to follow the comments_notify option, and the default for notes continues to follow the wp_notes_notify option regardless of approval status.
    • Returning true from the filter now sends the notification, even for an unapproved comment.

    Two smaller changes ship alongside this:

    • The default passed to the filter is now always a strict boolean. Previously the raw option value (for example the string '1') could be passed through, so callbacks that strictly compare the incoming $maybe_notify value should compare against true/false.
    • When the passed comment ID does not resolve to a valid comment, the function now returns false immediately without applying the filter. Previously, the filter still fired in this case.

    Who is affected

    Sites or plugins using a callback such as __return_true on notify_post_author to force notifications will now also receive emails for comments held in moderation, marked as spam, or trashed. If that is not desired, the callback should check the comment’s approval status:

    add_filter(
    	'notify_post_author',
    	function ( $maybe_notify, $comment_id ) {
    		$comment = get_comment( $comment_id );
    
    		// Only force notifications for approved comments.
    		if ( $comment && '1' === $comment->comment_approved ) {
    			return true;
    		}
    
    		return $maybe_notify;
    	},
    	10,
    	2
    );
    

    Callbacks that only suppress notifications (returning false) are unaffected, as are sites that do not filter notify_post_author at all.

    Props to @milana_cap for peer review.

    #7-1, #dev-notes, #dev-notes-7-1

    Filtering registered abilities with wp_get_abilities() in WordPress 7.1

    WordPress 7.1 extends wp_get_abilities() with a standard way to 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. registered abilities.

    The function now accepts an optional $args array that can filter abilities by category, namespace, or metadata. It also supports callbacks for custom per-item filtering and final result processing.

    Two new WordPress filters allow plugins to influence ability retrieval across the site:

    • wp_get_abilities_item_include
    • wp_get_abilities_result

    The REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/’s abilities list controller now uses wp_get_abilities() instead of implementing categoryCategory The 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging. filtering separately. It also supports filtering abilities by namespace.

    Why was this change needed?

    Before WordPress 7.1, there were two ways to retrieve abilities:

    // Retrieve every registered ability.
    $abilities = wp_get_abilities();
    
    // Retrieve one named ability.
    $ability = wp_get_ability( 'my-plugin/export-users' );
    

    wp_get_abilities() always returned the complete registry. A caller needing a subset had to retrieve every ability and filter the result manually:

    $abilities = array_filter(
    	wp_get_abilities(),
    	function ( WP_Ability $ability ): bool {
    		return 'data-export' === $ability->get_category();
    	}
    );
    

    Several consumers developed their own versions of this pattern for category, namespace, and metadata checks. The REST abilities controller also performed its own category filtering after retrieving the complete registry.

    This led to:

    • Duplicated filtering code.
    • Inconsistent filtering semantics between consumers.
    • Different behaviour between the PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher and REST APIs.
    • No standard extension points for ability selection.
    • Additional filtering passes over the registry.

    WordPress 7.1 moves this work into wp_get_abilities(), providing one shared filtering pipeline for CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. and plugins.

    Filtering by category

    Pass a category slug using the category argument:

    $abilities = wp_get_abilities(
    	array(
    		'category' => 'data-export',
    	)
    );
    

    The comparison is exact. Only abilities whose category exactly matches the supplied string are returned.

    The category must be passed as a single string. Arrays of category slugs are not supported.

    Filtering by namespace

    Use namespace to retrieve abilities registered under a particular namespace:

    $abilities = wp_get_abilities(
    	array(
    		'namespace' => 'my-plugin',
    	)
    );
    

    The namespace is passed without the trailing slash. Both of the following values are normalised to the same namespace:

    'namespace' => 'my-plugin',
    'namespace' => 'my-plugin/',
    

    An ability such as my-plugin/export-users matches, while another-plugin/export-users does not.

    Namespace matching includes the namespace delimiter. Passing my-plugin does not accidentally match an ability registered under a similarly named my-plugin-extra namespace.

    Filtering by metadata

    The meta argument selects abilities whose metadata contains the specified key-value pairs:

    $abilities = wp_get_abilities(
    	array(
    		'meta' => array(
    			'public' => true,
    		),
    	)
    );
    

    All supplied metadata conditions must match:

    $abilities = wp_get_abilities(
    	array(
    		'meta' => array(
    			'public'       => true,
    			'show_in_rest' => true,
    		),
    	)
    );
    

    Nested metadata is supported:

    $abilities = wp_get_abilities(
    	array(
    		'meta' => array(
    			'my_client' => array(
    				'public' => true,
    			),
    		),
    	)
    );
    

    Metadata comparisons are strict. The value true does not match 1, and false does not match 0.

    The metadata filter checks that every requested condition exists and matches. An ability may contain additional metadata that was not included in the query.

    Combining declarative filters

    The category, namespace, and meta arguments can be combined:

    $abilities = wp_get_abilities(
    	array(
    		'category'  => 'data-export',
    		'namespace' => 'my-plugin',
    		'meta'      => array(
    			'public' => true,
    		),
    	)
    );
    

    Conditions are combined using AND logic. An ability must satisfy every supplied argument to be included.

    In this example, the result contains only abilities that:

    • Belong to the data-export category.
    • Use the my-plugin namespace.
    • Have resolved public metadata set to true.

    Custom per-item filtering

    Conditions that cannot be expressed using the declarative arguments can be handled with item_include_callback:

    $abilities = wp_get_abilities(
    	array(
    		'namespace'             => 'my-plugin',
    		'item_include_callback' => function (
    			WP_Ability $ability
    		): bool {
    			return my_plugin_should_include_ability( $ability );
    		},
    	)
    );
    

    The callback runs once for every ability that passed the declarative filters. It receives the WP_Ability instance and must return a boolean:

    • Return true to include the ability.
    • Return false to exclude it.

    This callback is scoped to the current wp_get_abilities() call. It does not affect ability retrieval elsewhere.

    Use it for conditions such as:

    • Custom metadata relationships.
    • Context-dependent visibility.
    • Integration-specific rules.
    • Conditions involving more than one ability property.

    Processing the complete result

    Use result_callback when an operation requires the complete matched array:

    $abilities = wp_get_abilities(
    	array(
    		'namespace'       => 'my-plugin',
    		'result_callback' => function ( array $abilities ): array {
    			uasort(
    				$abilities,
    				function (
    					WP_Ability $first,
    					WP_Ability $second
    				): int {
    					return strcasecmp(
    						$first->get_label(),
    						$second->get_label()
    					);
    				}
    			);
    
    			return array_slice(
    				$abilities,
    				0,
    				10,
    				true
    			);
    		},
    	)
    );
    

    The result callback runs after all per-item matching has completed. It is suitable for:

    • Sorting.
    • Slicing or pagination.
    • Reordering.
    • Other final result transformations.

    Like item_include_callback, result_callback applies only to the current function call.

    Registered abilities are normally returned in an associative array keyed by ability name. When sorting or slicing the result, preserve those keys when downstream code depends on them.

    New global filters

    WordPress 7.1 also introduces two filters for plugins that need to affect ability retrieval beyond a single call site.

    wp_get_abilities_item_include

    The wp_get_abilities_item_include filter runs for every ability that passed the declarative conditions and the caller’s item_include_callback:

    add_filter(
    	'wp_get_abilities_item_include',
    	function (
    		bool $include,
    		WP_Ability $ability,
    		array $args
    	): bool {
    		if ( 'my-plugin/private-operation' === $ability->get_name() ) {
    			return false;
    		}
    
    		return $include;
    	},
    	10,
    	3
    );
    

    The filter receives:

    • $include: Whether the ability should currently be included.
    • $ability: The ability being evaluated.
    • $args: The complete arguments passed to wp_get_abilities().

    Because declarative mismatches are removed before this filter runs, the filter cannot add an ability that failed category, namespace, or meta matching. It can influence the inclusion of abilities that have reached this stage, as well as their global exclusion.

    wp_get_abilities_result

    The wp_get_abilities_result filter receives the complete result after the caller’s result_callback:

    add_filter(
    	'wp_get_abilities_result',
    	function ( array $abilities, array $args ): array {
    		// Apply site-wide result processing when appropriate.
    		return $abilities;
    	},
    	10,
    	2
    );
    

    The filter receives:

    • $abilities: The final matched array.
    • $args: The complete arguments passed to wp_get_abilities().

    It can be used for site-wide sorting, reordering, or other final processing.

    These are global filters. Plugins should use them only when the behaviour is intended to affect every relevant caller. For logic that belongs to one operation, prefer item_include_callback or result_callback.

    Filtering order

    The complete pipeline runs in the following order:

    1. Match the category argument.
    2. Match the namespace argument.
    3. Match the meta argument.
    4. Run item_include_callback.
    5. Apply wp_get_abilities_item_include.
    6. Add included abilities to the matched result.
    7. Run result_callback on the complete result.
    8. Apply wp_get_abilities_result.

    The declarative checks, item callback, and item filter run within a single pass over the registry.

    This avoids the separate array_filter() passes that consumers previously had to implement.

    Discovery over REST

    The REST collection endpoint delegates to wp_get_abilities() and exposes the declarative filters as query parameters:

    GET /wp-json/wp-abilities/v1/abilities?namespace=my-plugin
    GET /wp-json/wp-abilities/v1/abilities?category=my-plugin-content
    GET /wp-json/wp-abilities/v1/abilities?meta[annotations][readonly]=true
    

    Parameters can be combined and use the same AND logic.

    ?category=data-export&namespace=my-plugin
    

    Every collection request also forces meta.show_in_rest = true internally. Supplying another metadata query can’t reveal an ability that is hidden from REST. The endpoint still requires an authenticated WordPress user, and executing a listed ability still requires its permission callback to pass.

    Custom metadata needs a REST parameter schema if its query-string values should be coerced before strict comparison. Without one, 'true' will never match boolean true. The rest_abilities_collection_params filter extends the collection argument schema:

    add_filter(
    	'rest_abilities_collection_params',
    	static function ( array $params ): array {
    		$params['meta']['properties']['my_plugin'] = array(
    			'type'       => 'object',
    			'properties' => array(
    				'enabled' => array(
    					'type' => 'boolean',
    				),
    			),
    		);
    		return $params;
    	}
    );
    

    After that declaration, the REST API casts "true" to a boolean true before the value reaches the metadata-matching logic.

    GET /wp-json/wp-abilities/v1/abilities?meta[my_plugin][enabled]=true
    

    Built-in annotation types

    The known readonly, destructive, and idempotent annotation values are coerced from query strings to boolean values before strict matching. Core declares the schema for these standard ability annotations.

    Each accepts a boolean or null, so REST can correctly cast their query values without 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. extending the schema:

    ?meta[annotations][readonly]=true
    

    Use rest_abilities_collection_params filter when making additional metadata fields queryable, especially boolean, integer, number, array, or object values that cannot be matched correctly as untyped query strings.

    Backward compatibility

    The $args parameter is optional:

    $abilities = wp_get_abilities();
    

    Existing calls remain valid, and the function still returns an array of WP_Ability instances keyed by ability name.

    Code that manually filters the result can continue to work:

    $abilities = array_filter(
    	wp_get_abilities(),
    	'my_plugin_filter_abilities'
    );
    

    However, plugins should migrate common category, namespace, and metadata checks to the new arguments. Doing so reduces duplicated code and allows Core and other integrations to use consistent matching behaviour.

    One behavioural detail deserves particular attention: the two new global filters run even when wp_get_abilities() is called without arguments.

    As a result, the following call now means “retrieve abilities through the standard filtering pipeline”:

    $abilities = wp_get_abilities();
    

    It does not necessarily mean “retrieve raw registry contents,” because another plugin can alter the result through wp_get_abilities_item_include and wp_get_abilities_result.

    Retrieving the raw registry

    Code that specifically needs the complete, unfiltered registry can use WP_Abilities_Registry::get_all_registered():

    $registry  = WP_Abilities_Registry::get_instance();
    $abilities = $registry->get_all_registered();
    

    This bypasses:

    • Declarative filtering.
    • Caller callbacks.
    • wp_get_abilities_item_include
    • wp_get_abilities_result

    Most application and integration code should continue using wp_get_abilities(). Direct registry access is appropriate only when raw registered state is explicitly required, such as low-level debugging or registry inspection.

    Filtering does not replace authorisation

    Filtering controls which abilities are returned during discovery. It does not determine whether the current user may execute an ability.

    An ability’s permission_callback remains responsible for authorisation:

    'permission_callback' => function (): bool {
    	return current_user_can( 'manage_options' );
    },
    

    Developers should not assume that an ability returned by wp_get_abilities() is executable by the current user.

    Similarly, excluding an ability from a filtered result is not a security boundary. Any sensitive operation must enforce its permissions when the ability is executed.

    When to use each option

    Use declarative arguments for standard selection:

    wp_get_abilities(
    	array(
    		'category'  => 'data-export',
    		'namespace' => 'my-plugin',
    		'meta'      => array(
    			'public' => true,
    		),
    	)
    );
    

    Use item_include_callback for custom conditions that apply to one call:

    wp_get_abilities(
    	array(
    		'item_include_callback' => 'my_plugin_should_include_ability',
    	)
    );
    

    Use result_callback for call-specific sorting or slicing:

    wp_get_abilities(
    	array(
    		'result_callback' => 'my_plugin_prepare_ability_results',
    	)
    );
    

    Use wp_get_abilities_item_include or wp_get_abilities_result only for behaviour intended to affect ability retrieval across callers.

    Use WP_Abilities_Registry::get_all_registered() only when code explicitly requires raw, unfiltered registry data.

    Together, these changes make wp_get_abilities() the shared discovery and filtering primitive for the Abilities 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., replacing duplicated filtering implementations with a consistent, extensibleExtensible This is the ability to add additional functionality to the code. Plugins extend the WordPress core software. pipeline.

    These changes were introduced in changeset [62420] for TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #64990.

    Props to @benjamin_zekavica for peer review, and @gziolo for review, technical guidance, and suggested improvements.

    #abilities-api, #7-1, #dev-notes, #dev-notes-7-1, #rest-api

    Responsive block styles and configurable viewports in WordPress 7.1

    WordPress 7.1 introduces responsive style states for blocks. Styles can now be defined for Tablet and Mobile viewports both through Global Styles for each 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. type and on individual block instances. They can be applied to all block types (and their block style variations) that use core block supports such as typography, color, background, border, dimensions, spacing, and layout.

    The default style remains the base style and applies at every viewport. Tablet and Mobile styles override that base within their respective breakpoint ranges.

    It is now also possible to define custom values for the Tablet and Mobile viewports, using px, em or rem units.

    Defining responsive block styles in `theme.jsonJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML.`

    "styles": {
    		"blocks": {
    			"core/group": {
    				"spacing": {
    					"padding": {
    						"top": "3rem",
    						"right": "3rem",
    						"bottom": "3rem",
    						"left": "3rem"
    					}
    				},
    				"@mobile": {
    					"spacing": {
    						"padding": {
    							"top": "1rem",
    							"right": "1rem",
    							"bottom": "1rem",
    							"left": "1rem"
    						}
    					}
    				}
    			}
    		}
    	}

    Responsive and pseudo-states are nested from viewport to pseudo-state:

    "styles": {
    		"blocks": {
    			"core/button": {
    				"@mobile": {
    					":hover": {
    						"color": {
    							"background": "var:preset|color|contrast",
    							"text": "var:preset|color|base"
    						}
    					}
    				}
    			}
    		}
    	}

    Block instance attributes

    Responsive styles for an individual block are stored in the block’s existing style attribute, using the same @mobile and @tablet keys as Global Styles:

    <!-- wp:paragraph {"style":{"@mobile":{"typography":{"fontSize":"1rem"}}}} -->
    <p>Text with a responsive font size.</p>
    <!-- /wp:paragraph -->

    On the frontend, WordPress generates media-query-scoped CSSCSS Cascading Style Sheets. for the responsive values and adds a stable, generated class to the rendered block. Non-layout per-instance state declarations are marked `!important` so they can override the block’s default inline styles. Responsive layout values and `blockGap` are processed by the existing layout support and scoped with the block’s generated container class.

    Configurable breakpoints

    WordPress provides two responsive style breakpoints by default:

    StateMedia query
    @mobile@media (width <= 480px)
    @tablet@media (480px < width <= 782px)

    There is no @desktop style key. The block’s default style is the desktop/base style and continues to apply at smaller sizes for any property that is not overridden.

    Themes can customize the breakpoint widths with the new top-level settings.viewport values:

    "settings": {
    		"viewport": {
    			"mobile": "30rem",
    			"tablet": "45rem"
    		}
    	}

    This produces the following ranges:

    @media (width <= 30rem) { /* Mobile */ }
    @media (30rem < width <= 45rem) { /* Tablet */ }

    Breakpoint values must be non-negative numeric lengths using px, em, or rem. CSS functions, percentages, unitless values, and other units are ignored.

    If only one valid breakpoint is configured, it keeps its viewport name and uses a single maximum-width query. If neither value is valid, the defaults are used. When both are valid but the Tablet value is smaller than or equal to the Mobile value, only the Mobile breakpoint is used.

    The configured viewport widths are used by responsive block styles and block visibility, and are previewable via the editor’s device preview.

    settings.viewport is a top-level setting. It cannot be configured separately for individual block types.

    Opting out of responsive editing

    Sites that need to prevent users from making viewport-based styling changes can turn off responsive style editing with the responsiveEditingEnabled editor setting, which defaults to true:

    function example_disable_responsive_editing( $settings ) {
    	$settings['responsiveEditingEnabled'] = false;
    	return $settings;
    }
    add_filter( 'block_editor_settings_all', 'example_disable_responsive_editing' );

    When it is false, both entry points for choosing a viewport are removed: the “Responsive styles” toggle in the Editor’s View menu, and the “Viewport” group in the “States” dropdown in Global Styles. Device previews still work, and pseudo states such as Hover remain available.

    The setting governs the editing interface only. Responsive styles already saved in theme.json, in Global Styles, or in a block’s style attribute are left untouched, and the media-query CSS described above is still generated for them, so existing content renders exactly as before both in the Editor and on the front end.

    Reviewed by @tyxla; props @ramonopoly, @wildworks

    #7-1, #dev-notes, #dev-notes-7-1

    Pseudo and custom style states in WordPress 7.1

    Pseudo states

    In WordPress 7.1, users have more power over styling the pseudo states of blocks. Currently limited to the Button and Navigation Link blocks, users are able to apply styles to ‘hover’, ‘focus’, ‘focus-visible’ and ‘active’ states.

    Pseudo states support definitions in theme.jsonJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. for themers, and blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. styling in global styles and on block instances for users.

    Defining pseudo states for blocks in theme.json

    Define pseudo states within the block object using the properties “:hover”, “:focus”, “:focus-visible”, and “:active”. Pseudo state names are always prefixed with a :.

    "styles": {
    	"blocks": {
    		"core/button": {
    			"color": {
    				"background": "black",
    				"text": "white"
    			},
    			":hover": {
    				"color": {
    					"background": "blue"
    				}
    			},
    			":focus": {
    				"color": {
    					"background": "purple"
    				}
    			}
    		}
    	}
    }
    

    Pseudo states can also be nested within responsive states:

    "styles": {
    	"blocks": {
    		"core/button": {
    			"@mobile": {
    				":hover": {
    					"color": {
    						"background": "var:preset|color|contrast",
    						"text": "var:preset|color|base"
    					}
    				}
    			}
    		}
    	}
    }

    Block instance attributes

    The structure for block instance attributes is very similar to the theme.json definition with :hover properties used inside the style attribute:

    <!-- wp:button {"backgroundColor":"accent-3","style":{":hover":{"color":{"background":"var:preset|color|accent-2"}}}} -->
    <div class="wp-block-button"><a class="wp-block-button__link has-accent-3-background-color has-background wp-element-button">Button with pseudo state background</a></div>
    <!-- /wp:button -->

    Custom style states

    Custom states are an early feature limited to theme.json definition only (no user facing features are exposed) and only the navigation link block. The navigation block uses this to allow styling of the current menu item – that is the menu item whose link matches that of the currently viewed page.

    Defining custom states for the navigation link block in theme.json

    Styles for the current menu item can be defined using the -current property. Custom states always use the -prefix.

    "styles": {
    	"blocks": {
    		"core/navigation-link": {
    			"-current": {
    				"color": {
    					"text": "var:preset|color|contrast"
    				},
    				":hover": {
    					"color": {
    						"text": "var:preset|color|accent-1"
    					}
    				}
    			}
    		}
    	}
    }

    As shown above, pseudo states can be nested within custom states. Custom states can also be nested within responsive states.

    Style generation

    The styles defined for custom states generate css that targets a class name selector. For the navigation link block, that would expand to something like .wp-block-navigation-link .current-menu-item { // styles ... }.

    The styles css class name that’s generated in the selector would be declared on supported blocks via a block’s block.json selectors property:

    "selectors": {
    	"states": {
    		"-current": ".wp-block-navigation-link .current-menu-item"
    	}
    }

    Opting out of style state editing

    Sites can prevent users from styling block states via the blockStatesEditingEnabled editor setting:

    function example_disable_block_states_editing( $settings ) {
    	$settings['blockStatesEditingEnabled'] = false;
    	return $settings;
    }
    add_filter( 'block_editor_settings_all', 'example_disable_block_states_editing' );

    blockStatesEditingEnabled defaults to true.

    When it is false, both the state dropdown in the block inspector’s block card, and the pseudo state options in the “States” dropdown in Global Styles under Styles > Blocks are hidden.

    The states affected are the pseudo states, Hover, Focus, Focus-visible and Active, which currently apply to the Button and Navigation Link blocks. In the future this will extend to other states present in the dropdown, like the ability for users to set styles for the Navigation Link’s ‘Current’ state.

    This setting does not affect viewport states. Those are controlled separately by responsiveEditingEnabled. Set both to false to remove the state editing interface entirely.

    The setting governs the editing interface only. State styles already saved in theme.json, in Global Styles, or in a block’s style attribute are left untouched and are still applied, so existing content renders exactly as before both in the Editor and on the front end.

    Reviewed by @ramonopoly, @andrewserong; props @wildworks

    #7-1, #dev-notes, #dev-notes-7-1

    A unified public exposure flag for Abilities in WordPress 7.1

    WordPress 7.1 introduces a new public metadata flag for abilities. The flag provides a single, high-level way to indicate that an ability is intended to be available to external clients such as the REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/, MCP adapters, and AI agents.

    Table of contents:

    Previously, ability authors had to express that intent separately for every exposure channel. For example, an ability exposed through the REST API needed to set show_in_rest directly:

    'meta' => array(
    	'show_in_rest' => true,
    ),
    

    As the Abilities 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. gains more client integrations, repeating the same intent through several channel-specific flags becomes difficult to maintain. The new public flag establishes a common default while preserving granular control for each channel.

    Registering a public ability

    An ability intended for client exposure can now set meta.public when it is registered:

    function my_plugin_register_abilities(): void {
    	wp_register_ability(
    		'my-plugin/export-users',
    		array(
    			'label'               => __( 'Export users', 'my-plugin' ),
    			'description'         => __( 'Exports user data as CSV.', 'my-plugin' ),
    			'category'            => 'data-export',
    			'execute_callback'    => 'my_plugin_export_users',
    			'permission_callback' => function (): bool {
    				return current_user_can( 'export' );
    			},
    			'meta'                => array(
    				'public' => true,
    			),
    		)
    	);
    }
    
    add_action( 'wp_abilities_api_init', 'my_plugin_register_abilities' );
    

    For the REST API, setting public to true makes show_in_rest default to true. The ability can therefore be discovered and invoked through the REST abilities endpoints, subject to its permission callback.

    How exposure defaults are resolved

    Channel-specific settings take precedence over the general public setting. The effective REST exposure value is resolved as follows:

    $show_in_rest = $meta['show_in_rest'] ?? $meta['public'] ?? false;
    

    For example, an ability that is generally public but must not be exposed through REST can use:

    'meta' => array(
    	'public'       => true,
    	'show_in_rest' => false,
    ),
    

    The explicit show_in_rest value wins over public.

    Conversely, an ability that is not generally public can still opt into REST specifically:

    'meta' => array(
    	'public'       => false,
    	'show_in_rest' => true,
    ),
    

    The resolution uses null-coalescing semantics so an explicit false is preserved. It is not treated as a missing value.

    A null value is treated as unset and falls back to the next value in the chain.

    In practical terms:

    Registration metadataEffective publicEffective show_in_rest
    No exposure metadatafalsefalse
    public => truetruetrue
    public => falsefalsefalse
    show_in_rest => truefalsetrue
    public => true, show_in_rest => falsetruefalse
    public => false, show_in_rest => truefalsetrue

    This precedence allows for a broad exposure default while opting in or out of individual channels.

    What problem does this change fix?

    Ability metadata already contained channel-specific exposure settings such as show_in_rest. As support for MCP, AI agents, and other clients develops, requiring ability authors to configure each channel independently would duplicate the same policy across multiple properties:

    'meta' => array(
    	'show_in_rest' => true,
    	'mcp'          => array(
    		'public' => true,
    	),
    	// Additional flags for future clients.
    ),
    

    This also makes it difficult for a newly introduced channel to determine whether an existing ability was intended for external use.

    The public flag fixes this by recording the ability author’s general exposure intent in one stable location:

    'meta' => array(
    	'public' => true,
    ),
    

    Individual integrations can use that value as their default while retaining a more specific channel-level override.

    REST is the first built-in consumer of this behaviour. Other integrations can adopt the same default without adding channel-specific logic to WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress..

    Using public in other integrations

    The resolved public value remains available in the ability’s metadata. Client integrations can inspect this value when determining whether an ability should be exposed.

    The WordPress MCP Adapter will respect the unified public flag starting with its next release. 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/ does not apply this exposure check because its ability-listing functionality returns all registered abilities.

    Other integrations should generally resolve exposure when abilities are selected for that integration:

    function my_plugin_is_ability_exposed(
    	WP_Ability $ability,
    	string $channel
    ): bool {
    	$meta = $ability->get_meta();
    
    	return $meta[ $channel ]['public'] ?? $meta['public'] ?? false;
    }
    

    Integrations that need to derive their own channel-specific metadata during registration can use the existing wp_register_ability_args 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.:

    add_filter(
    	'wp_register_ability_args',
    	function ( array $args, string $name ): array {
    		if (
    			! isset( $args['meta']['my_client']['public'] )
    			&& isset( $args['meta']['public'] )
    		) {
    			$args['meta']['my_client']['public'] =
    				(bool) $args['meta']['public'];
    		}
    
    		return $args;
    	},
    	10,
    	2
    );
    

    An integration should follow the same precedence rule as REST:

    1. Use an explicit channel-specific value when present.
    2. Otherwise, inherit public.
    3. Otherwise, use the channel’s built-in default.

    Integrations should not overwrite an explicit channel opt-out merely because public is true.

    Exposure is not authorisation

    The public flag controls discoverability and client exposure. It does not make an ability executable without authorisation, and it does not replace the ability’s permission_callback.

    Every ability must continue to implement an appropriate permission check:

    'permission_callback' => function (): bool {
    	return current_user_can( 'manage_options' );
    },
    

    An ability with public => true may be visible through a client while still requiring authentication and specific WordPress capabilitiescapability 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 execute.

    Developers should not treat public, show_in_rest, or any other exposure flag as a security boundary. Authorisation must be enforced by the ability itself.

    Changes to resolved metadata

    In WordPress 7.1, the resolved metadata for every ability includes a boolean public property. It defaults to false when it is not supplied during registration.

    For example:

    $ability = wp_get_ability( 'my-plugin/export-users' );
    $meta    = $ability->get_meta();
    
    $is_public = $meta['public']; // Always a boolean in WordPress 7.1.
    

    This gives consumers a consistent value to inspect without having to test whether the key exists.

    The new property is also declared in the REST API’s ability metadata schema, allowing REST clients to inspect the general exposure intent.

    Backward compatibility

    The change does not alter the signature or return value of wp_register_ability() or other Abilities API functions.

    Existing channel-specific registrations continue to work:

    'meta' => array(
    	'show_in_rest' => true,
    ),
    

    An explicit show_in_rest value remains authoritative. Plugins are not required to replace it with public.

    Abilities that previously supplied neither public nor show_in_rest remain unavailable through REST. Their resolved metadata now contains public => false, but their exposure behaviour is unchanged.

    Developers should consider migrating from show_in_rest => true to public => true when an ability is generally intended for use by multiple client types. Continue using show_in_rest directly when exposure is intentionally limited to REST or when overriding the general policy.

    Existing Core abilities

    The following abilities included with WordPress now use meta.public instead of setting meta.show_in_rest directly:

    • core/get-site-info
    • core/get-user-info
    • core/get-environment-info

    Their REST availability has not changed. Because public => true supplies the default for show_in_rest, these abilities remain exposed through REST as before.

    Using the high-level flag also allows other client integrations to recognise that these Core abilities are intended for external use.

    When to use each flag

    Use public when the ability is generally intended for consumption by external clients.

    Use a channel-specific flag when:

    • The ability should be exposed through only that channel.
    • The ability needs to opt out of a channel despite being generally public.
    • A client integration provides behaviour that cannot be represented by the general flag.

    The change was introduced in changeset [62729], with Core abilities migrated in changeset [62737]. See TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #65568 for the complete discussion.

    Props to @gziolo and @benjamin_zekavica for peer review.

    #abilities-api, #7-1, #dev-notes, #dev-notes-7-1, #rest-api

    Miscellaneous Editor Changes in WordPress 7.1

    In this post, you will find dev notesdev 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. for smaller changes to the editor in WordPress 7.1.

    Table of contents

    Blocks

    The Navigation block will no longer forcefully propagate its font-size configurations down to the markup of individual child blocks (core/navigation-link, core/navigation-submenu, core/page-list, and core/home-link).

    Currently, font size is propagated to every navigation item. Because relative units multiply against their parent container’s computed size, this caused extreme compounding (e.g., 1.5em2.25em3.375em), severely breaking the layout of deeply nested dropdown menus.

    By removing the explicit application on child items, the Navigation block now safely relies on standard CSSCSS Cascading Style Sheets. text inheritance. This fixes an issue where the editor canvas and the frontend displayed mismatched typography sizes when child links had their own explicit font sizes overridden by parent propagation.

    As for backwards compatibility, theme developers can restore the legacy font-size propagation behavior by applying the following 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. in their functions.php:

    /**
     * Restores font size classes on Navigation child blocks.
     * Use this if your theme targets has-{slug}-font-size on nav items directly.
     */
    function restore_nav_item_font_size( $block_content, $parsed_block, $block ) {
        $context = $block->context;
    
        $has_named_font_size  = array_key_exists( 'fontSize', $context );
        $has_custom_font_size = isset( $context['style']['typography']['fontSize'] );
    
        if ( ! $has_named_font_size && ! $has_custom_font_size ) {
            return $block_content;
        }
    
        $target_tag = 'core/page-list' === $block->name ? 'UL' : 'LI';
    
        $processor = new WP_HTML_Tag_Processor( $block_content );
    
        if ( ! $processor->next_tag() || $target_tag !== $processor->get_tag() ) {
            return $block_content;
        }
    
        if ( $has_named_font_size ) {
            $processor->add_class( sprintf( 'has-%s-font-size', $context['fontSize'] ) );
        } elseif ( $has_custom_font_size ) {
            $existing_style  = $processor->get_attribute( 'style' ) ?? '';
            $font_size_style = sprintf(
                'font-size: %s;',
                wp_get_typography_font_size_value(
                    array( 'size' => $context['style']['typography']['fontSize'] )
                )
            );
            $processor->set_attribute( 'style', $existing_style . $font_size_style );
        }
    
        return $processor->get_updated_html();
    }
    
    add_filter( 'render_block_core/navigation-link', 'restore_nav_item_font_size', 10, 3 );
    add_filter( 'render_block_core/navigation-submenu', 'restore_nav_item_font_size', 10, 3 );
    add_filter( 'render_block_core/home-link', 'restore_nav_item_font_size', 10, 3 );
    add_filter( 'render_block_core/page-list', 'restore_nav_item_font_size', 10, 3 );

    References:

    Targeting Block Variations in Block Transforms

    It’s now possible to target a specific block variation in a block transform, via the optional variationName property:

    transforms: {
    	to: [
    		{
    			type: 'block',
    			blocks: [ 'core/group' ],
    			variationName: 'group-grid',
    			transform: ( attributes, innerBlocks ) => {
    				return createBlock(
    					'core/group',
    					{
    						...attributes,
    						layout: { type: 'grid' },
    					},
    					innerBlocks
    				);
    			},
    		},
    	],
    }

    For programmatic transforms, switchToBlockType now accepts the target variation name as an optional third argument:

    switchToBlockType( blocks, 'core/group', 'group-grid' );

    References:

    Stabilize cloneSanitizedBlock and sanitizeBlockAttributes

    The @wordpress/blocks package and wp.blocks global have two functions, __experimentalCloneSanitizedBlock and __experimentalSanitizeBlockAttributes.

    These functions will continue to work in WordPress 7.1, but they will now log deprecation messages to the console. The functions have been replaced with stable versions that do not have the __experimental prefix.

    Developers should replace any usage of __experimentalCloneSanitizedBlock with cloneSanitizedBlock and __experimentalSanitizeBlockAttributes with sanitizeBlockAttributes.

    References:

    Updated Markdown parsing library

    @wordpress/blocks replaced showdown with marked for parsing pasted Markdown. The parser is internal to pasteHandler() and was never exported, so no code changes are needed.

    Output should be equivalent, but edge cases now follow the CommonMark and GFM specs. Consumers calling pasteHandler() directly should re-test representative Markdown input against the blocks it produces.

    References:

    Editor

    Template parts can opt out of content-only editing

    WordPress 7.1 introduces a disableContentOnlyForTemplateParts editor setting, letting themes and plugins restore standard block editing for Template Parts instead of the content-only editing used by default.

    Set it via the block_editor_settings_all filter in PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher:

    add_filter( 'block_editor_settings_all', function ( $settings ) {
    	$settings['disableContentOnlyForTemplateParts'] = true;
    	return $settings;
    } );

    Or at runtime from 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:

    wp.data.dispatch( 'core/block-editor' ).updateSettings( {
    	disableContentOnlyForTemplateParts: true,
    } );

    When the editor is in template-locked rendering mode, content-only editing for Template Parts is always disabled regardless of this setting.

    There is no impact on backward compatibility: leaving the setting unset preserves the existing default behavior.

    For a session-only toggle while editing, the command palette also offers an “Enable/Disable content-only editing for patterns and template parts” command.

    References:

    Global Styles

    Block-level preset classes now match root-level specificity

    WordPress 7.1 lowers the CSS specificity of the preset utility classes (.has-*-color, -background-color, -border-color, -gradient-background, -font-size, -font-family) generated for block-level presets, so they match the specificity of top-level (root) presets.

    Presets defined at the block level, that is, via theme.json settings.blocks.<block> or the wp_theme_json_data_* filters, used to prepend the block selector to the preset class, raising its specificity above top-level presets.

    The block selector is now wrapped in :where(), which contributes no specificity.

    Before:

    .has-accent-color                { color: … !important; } /* top level:   0-1-0 */
    p.has-accent-color               { color: … !important; } /* block level: 0-1-1 */
    .wp-block-group.has-accent-color { color: … !important; } /* block level: 0-2-0 */

    After:

    :where(p).has-accent-color               { color: … !important; } /* 0-1-0 */
    :where(.wp-block-group).has-accent-color { color: … !important; } /* 0-1-0 */

    Scoping is unchanged. The rule still only matches the class on/within that block. Top-level presets are unchanged.

    The reason for the change is that block-level presets out-ranking top-level ones was inconsistent and broke the responsive style states also landing in 7.1. Preset classes and responsive state styles both use !important, so specificity picked the winner. For example, a block-level palette colour set for Desktop overrode one set for Mobile. At equal specificity the responsive rule now wins on source order, as intended.

    Affected are themes and plugins that register block-level presets and depend on their former, higher specificity. For example custom CSS written to slot between a top-level and a block-level preset. Such rules now tie block-level presets at 0-1-0.

    The risk of regressionregression A software bug that breaks or degrades something that previously worked. Regressions are often treated as critical bugs or blockers. Recent regressions may be given higher priorities. A "3.6 regression" would be a bug in 3.6 that worked as intended in 3.5. is relatively contained because:

    • presets flow through CSS variables, so only collision tie-breaks change, not rendered values.
    • only !important author CSS ever competed with presets, and the drop is a single component in each case: 0-1-1 to 0-1-0 for element-based block selectors, 0-2-0 to 0-1-0 for class-based ones.
    • :where() is already used throughout 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/ to manage specificity.
    • Realistic collisions are dominated by the responsive-states 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. this fixes. Responsive states are new to 7.1.

    References:

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

    Non-paginated entities now return all records

    Several 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/ endpoints ignore the page and per_page collection parameters and always return the entire collection. getEntityRecords() applied client-side pagination to every entity, slicing responses to the default per_page of 10 and ignoring remaining records. That was a bug.

    The unintended behavior has been corrected: slicing now only happens for entities that declare supportsPagination: true, and everything else returns the full collection.

    The common per_page: -1 workaround is no longer necessary, though passing it remains harmless. If you were getting a short list back from one of these entities, you’ll now get all of them, so take a look anywhere you render or 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 over the results without setting your own limit. Custom entities backed by a non-paginated REST route should declare supportsPagination: false.

    References:

    Deprecating legacy editor packages

    @wordpress/nux: Now a no-op compatibility package

    Starting in WordPress 7.1, the @wordpress/nux package becomes a no-op compatibility package.

    The package has been deprecated since WordPress 5.4. It remains available so existing imports and script dependencies do not break, but it no longer displays tips or guides.

    If you still rely on NUX for onboarding, migrate to the Guide component from @wordpress/components instead.

    References:

    @wordpress/reusable-blocks: Public APIs now log deprecation warnings

    The @wordpress/reusable-blocks package components and data APIs will log deprecation warnings starting from WordPress 7.1.

    The package only exposed experimental APIs, and it hasn’t been used by the core since 2023. If your code needs to fetch or update Synced Patterns (formerly known as Reusable Blocks) on the client side, use the standard core entity methods.

    This deprecation prepares the packages for a no-op backward compatibility update, similar to @wordpress/nux.

    References:

    Props to @ellatrix, @isabel_brison, @mamaduka, @ramonopoly, @sarthaknagoshe2002, @talldanwp, and @0mirka00 for content, and to @ramonopoly and @tyxla for review.

    #7-1, #dev-notes, #dev-notes-7-1

    Dev Chat Agenda – August 4, 2026

    The next WordPress Developers Chat will take place on Tuesday, August 4, 2026, at 15:00 UTC in the core channel on Make WordPress Slack.

    The live meeting will focus on the discussion for upcoming releases, and have an open floor section.

    The various curated agenda sections below refer to additional items. If you have ticketticket Created for both bug reports and feature development on the bug tracker. requests for help, please continue to post details in the comments section at the end of this agenda or bring them up during the dev chat.

    Announcements 📢

    Note: Dev Chat has been moved to Tuesdays at 15:00 UTC for the duration of the 7.1 release cycle.

    7.1

    General

    Discussions 💬

    The discussion section of the agenda is for discussing important topics affecting the upcoming release or larger initiatives that impact the CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. Team. To nominate a topic for discussion, please leave a comment on this agenda with a summary of the topic, any relevant links that will help people get context for the discussion, and what kind of feedback you are looking for from others participating in the discussion.

    Open floor  🎙️

    Any topic can be raised for discussion in the comments, as well as requests for assistance on tickets. Tickets in the milestone for the next major or maintenance release will be prioritized.

    Please include details of tickets / PRs and the links in the comments, and indicate whether you intend to be available during the meeting for discussion or will be async.

    #7-1, #agenda, #core, #dev-chat