The WordPress coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. development team builds WordPress! Follow this site for general updates, status reports, and the occasional code debate. There’s lots of ways to contribute:
Found a bugbugA 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.?Create a ticket in the bug tracker.
WordPress 6.8 introduces speculative loading, which can lead to near-instant page load times by loading URLs before the user navigates to them. The feature relies on the Speculation Rules API, a web platform feature that allows defining rules for which kinds of URLs to prefetch or prerender, and how early such speculative loading should occur.
Please refer to the speculative loading announcement post for additional information about the Speculation Rules APIAPIAn 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. and related prior art in WordPress CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress..
Context
Prior to being implemented in WordPress Core, the feature has been successfully used on over 50,000 WordPress sites via the Speculative Loading feature plugin, which has been ported over to Core now, with a few modifications. Based on data queried from the HTTP Archive and Chrome User Experience Report (CrUX) datasets over all the time since the pluginPluginA 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 launched, the sites that enabled speculative loading improved their Largest Contentful Paint (LCP) passing rate by ~1.9% at the median which, while it may seem a small number, is a huge boost for a single feature, considering that a lot of sites with various performance implications contribute to the data.
The Speculation Rules API is supported by Chrome, Edge, and Opera so far, which means the vast majority of end users browsing the web can benefit from its capabilities. For users of browsers without support for the API, there are no adverse effects, since the Speculation Rules API is a progressive enhancementenhancementEnhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature.. Browsers without support simply ignore its presence, i.e. sites maintain the same behavior as before.
Default behavior and customization
The WordPress Core implementation enables speculative loading by default in the frontend of all sites, except when a user is logged in or when a site has pretty permalinks disabled. URLs are prefetched with conservative eagerness: this means that prefetching is triggered when a user starts to click on a link. While this is typically only a fraction of a second before the actual navigation occurs, it is still enough to lead to a notable performance improvement.
This default of prefetch with conservative eagerness is used as a reasonable starting point to enable speculative loading at the scale of WordPress. It is in line with the configuration that Cloudflare uses in its speculative loading feature, and it minimizes the chance of any speculative loads without a subsequent navigation to the URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org. The Speculative Loading plugin uses a default of prerender with moderate eagerness, which leads to a larger performance improvement due to the speculative load being triggered earlier as well as prerendering the URL, but also has tradeoffs related to certain client-side behavior inadvertently being triggered even in case the user never ends up navigating to the URL.
Customization via actions and filters
Excluding URL patterns from speculative loading
When a URL is prefetched, the server response is loaded before the user navigates to it. In most cases, this is not an issue since server responses for frontend URLs do not typically change the state of the site in any way. However, there may be plugins that use the pattern of so-called “action URLs”, where simply navigating to a specific URL (with a GET request) a state change occurs—for example on an e-commerce WordPress site, it could be adding a product to the shopping cart or marking an item as a favorite. It is worth noting that this is an antipattern, since state changes should typically be triggered only by POST requests, e.g. via form submissions, and GET requests are supposed to be “idempotent”. Despite that, plugins that use this pattern should ensure that such URLs are excluded from prefetching and prerendering. In the case of conservative eagerness, this should not be an issue since it’s almost guaranteed the user will also navigate to the URL. But for sites that use a more eager configuration there is a chance the navigation will never occur, which is why excluding such URLs is important.
By default, any URLs that include query parameters are excluded from prefetching and prerendering automatically, which should cater for the majority of such action URLs. However, in case a plugin is implementing its own rewrite rules for these URLs instead of using custom query parameters, they can use the wp_speculation_rules_href_exclude_pathsfilterFilterFilters 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. to provide URL patterns to exclude.
This example ensures that any URLs with a path starting in “/cart/” will be excluded from speculative loading, regardless of whether it’s prefetch or prerender:
All URL patterns provided should follow the URL Pattern web specification, and they will all be considered relative to the frontend of the site. For sites where the home URL is in a subdirectory, WordPress will automatically prefix the corresponding path segment so that plugin developers do not need to worry about that.
While WordPress Core’s default behavior is to prefetch URLs, sites may opt in to prerendering URLs. This leads to a significant performance boost, but also has additional implications on the speculatively loaded URLs, since even their client-side code will be loaded. If a site contains any client-side logic that should only run once the user actually navigates to the URL, it needs to check for whether the site is being prerendered first and only trigger such logic once the navigation has occurred (see “Detect prerender in JavaScript” documentation). A common use-case for that is analytics tooling (see “Impact on analytics” documentation). Many popular providers already support prerendering, so no change is necessary. But if your site or your plugin includes such functionality on certain URLs and you haven’t updated the JavaScriptJavaScriptJavaScript 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/. logic to support prerendering yet, you can temporarily exclude the relevant URLs from prerendering specifically.
This example ensures that any URLs with a path starting in “/personalized-area/” will be excluded from prerender speculative loading only:
Modifying the default speculative loading configuration
As mentioned before, WordPress sites are able to modify the default speculative loading configuration. For further improved performance, you may want the configuration to be more eager or to leverage prerendering. This can be achieved via the wp_speculation_rules_configuration filter, which receives either an associative array with mode and eagerness keys to control the configuration, or null to disable speculative loading for the current request.
The default value for the filter is array( 'mode' => 'auto', 'eagerness' => 'auto' ), unless a user is logged-in or the site has pretty permalinks disabled, in which case the default value is null. For both configuration parameters, the value auto signifies that WordPress Core will decide on the configuration, which as of today effectively leads to a mode of prefetch and an eagerness of conservative. Depending on various criteria such as the state of the Speculation Rules API and ecosystem support, the behavior may change in a future WordPress release.
Here is an example that uses the filter to increase the eagerness to moderate. This will improve the performance benefits, while increasing the tradeoff for a speculative load without subsequent navigation:
The mode value can be either auto, prefetch, or prerender, and the eagerness value can be either auto, conservative, moderate, or eager. The Speculation Rules API also defines another eagerness value of immediate, however that value is strongly discouraged for document-level rules that speculatively load any URLs, so the WordPress Core API does not allow using it for its overall configuration.
If you wanted to opt for an even greater performance boost, here is an example that uses the filter to opt for prerender with moderate eagerness. This is similar to what the Speculative Loading feature plugin implements, and it can lead to a significant performance boost. Please keep in mind the effects of prerendering on client-side JavaScript logic explained in the previous section before enabling prerender.
As mentioned before, speculative loading is disabled by default for sites that do not use pretty permalinks. This is because the aforementioned exclusion of URLs with query parameters would not reliably apply anymore if even WordPress Core’s arguments used query parameters. There may however be cases where, as a site owner of a site without pretty permalinks, you are confident that your site is not using any of the problematic patterns that are the reason for this exclusion in the first place, or you already identified them and explicitly excluded URLs with the specific query parameters from being speculatively loaded. In that case, you could use the filter to enable speculative loading, as seen here:
Please use caution when opting into speculative loading like this. WordPress Core’s defaults were carefully considered to cater for the majority of sites in a safe way, so only use this code snippet if you are confident it will not have adverse effects on your site.
Including additional speculation rules
The Speculation Rules API allows defining multiple rules to configure how the browser should speculatively load URLs. By default, WordPress Core only includes a single rule that handles all the aforementioned behavior. More advanced customization is possible by providing entirely new speculation rules in addition to Core’s main rule, which can be accomplished by using the wp_load_speculation_rules action. The action receives an instance of the new WP_Speculation_Rules class, which has validation mechanisms built in and can be amended as needed. By adding new rules, you can implement entirely custom configurations that will be applied on top of WordPress Core’s main rule.
Here is an example, which directly relates to the previous example that changes the default configuration to prerender with moderate eagerness. You may prefer not to change the default, but there may be specific URLs where you would like to enable prerender with moderate eagerness. You could add a custom URL-level speculation rule for that:
Taking this example further, maybe there is no easy way to provide a list of URLs, e.g. in case they change often or more URLs need to be added regularly. In that case, you consider using a document-level speculation rule that applies for all links that are marked with a specific class, or where a parent element has a specific class:
With this rule in place, users would be able to add a moderate-prerender class to any blockBlockBlock 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. that supports the advanced UIUIUser interface for adding classes, and that way they could manually opt in any link on demand.
Please refer to the Speculation Rules API specification for details on what a rule definition can look like.
Customization via UI
The previous example already hints at how speculative loading can be customized via the UI. While a dedicated UI for the feature like it exists in the Speculative Loading feature plugin is out of scope for WordPress Core, many block types provide an “Additional CSSCSSCascading Style Sheets. class(es)” field in the “Advanced” panel in the block sidebarSidebarA 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..
WordPress Core has built-in support for the CSS classes no-prefetch and no-prerender. You can add these to any block so that links within that block are opted out of prefetching or prerendering respectively. Note that no-prefetch opts out of both, i.e. opts out of speculative loading entirely, since prefetching is part of prerendering. Please refer to the section about excluding URL patterns for guidance on when it may be useful to exclude URLs from prefetching or prerendering.
This mechanism makes it easy for advanced users to take granular control over speculative loading for specific blocks.
Summary and further reading
The speculative loading feature in WordPress 6.8 is a great win for performance of WordPress and the web overall, by starting the page load process even before the user navigation occurs. By fine-tuning it further based on your site’s needs, you can achieve even greater performance boosts than with the default configuration.
Please see the following links for further reading:
TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.ticketticketCreated for both bug reports and feature development on the bug tracker.#62503 and changeset [59837] for additional context and discussion about the Core implementation.
Note: This article has been updated with additional technical information about the structure of password hashes that may be relevant to developers of plugins that directly handle them.
The underlying algorithm that’s used to hash and store user passwords in the database will be changed in WordPress 6.8 from phpass portable hashing to bcrypt. The adoption of bcrypt hardens password security in WordPress by significantly increasing the computational cost of cracking a password hash.
In addition, application passwords, user password reset keys, personal data request keys, and the recovery mode key will switch from using phpass to the cryptographically secure but fast BLAKE2b hashing algorithm via Sodium.
No action needs to be taken by site owners or users as a result of these changes. Passwords and security keys that were saved in prior versions of WordPress will continue to work after updating to 6.8. Users don’t need to change or reset their passwords, logged in users will remain logged in, and their sessions will remain valid.
When a user first subsequently logs in after the update – or when they next change their password – their password will automatically get rehashed with bcrypt and resaved in the database. Application passwords and security keys will not get automatically rehashed, but an existing hash will remain valid if it was generated prior to WordPress 6.8 and used before it expires.
Note that post passwords will continue to use phpass portable hashing for now. This may change in the future after further investigation has been done on how best to improve the hashing and checking mechanism of post passwords.
Portability
Hashes that are generated by the phpass portable hashing algorithm are portable between different sites, environments, and servers. This portability doesn’t change with this switch to bcrypt and BLAKE2b, so you can move your database from one server to another and update to newer versions of PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher and WordPress and the password hashes will continue to function as expected.
Updates to password handling functions
The wp_hash_password() and wp_check_password() functions have been updated to use the PHP native password_hash() and password_verify() functions with the bcrypt algorithm and SHA-384 pre-hashing. Both functions retain support for the $wp_hasher global object in case that’s being used to implement an alternative hashing mechanism.
The wp_check_password() function retains support for passwords that were hashed using phpass, which means existing password hashes won’t be invalidated.
A new wp_password_needs_rehash() function has been introduced as a wrapper for password_needs_rehash(). If a pluginPluginA 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 needs to adjust its logic then the password_needs_rehashfilterFilterFilters 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. can be used. The function is also pluggable, so it can be overridden if absolutely necessary.
Pre-hashing with SHA-384 is implemented in order to avoid the 72 byte length limit imposed on passwords by bcrypt. Password hashes are therefore stored with a $wp prefix to distinguish them from vanilla bcrypt hashes which may be in use via a plugin. By default this means the full prefix will be $wp$2y$.
New fast hashing functions
The following functions have been introduced as wrappers for the cryptographically secure but fast BLAKE2b algorithm via Sodium:
wp_fast_hash() Used to hash a string that is randomly generated using sufficiently high entropy, preferably over 128 bits for values that don’t have a corresponding expiry mechanism.
wp_verify_fast_hash() Used to verify a hash generated via wp_fast_hash(), with fallback support for phpass portable hashes.
Do developers need to do anything?
Code that calls wp_hash_password() and wp_check_password() will continue to work as expected and does not need to change.
Code that directly handles phpass hashes may need to be updated, for example:
Code that assumes the existence of the $P$ prefix on hashes. The code will need to be updated so it either doesn’t need to inspect the prefix of the hash at all, or updated to handle both the new prefixes and hashing algorithms and legacy hashes:
The $wp$2y$ prefix will be the new default for user passwords in WordPress and represents a SHA-384 pre-hashed bcrypt hash.
The plain $2y$ prefix may be used by existing plugins that use bcrypt hashes without pre-hashing.
The $generic$ prefix for a BLAKE2b hash used for application passwords and security keys.
A hash starting with $argon2 if a site opts in to using an Argon2 algorithm (see below). Note that any non-bcrypt algorithm won’t use pre-hashing and therefore won’t include $wp at the start of the prefix.
The old $P$ prefix for a phpass portable hash which will remain in wide use.
A legacy plain MD5 hash, which is a 32 character hexadecimal string.
Code that otherwise directly interacts with the hashed value of a user password. If such hashes are validated directly, this should be done via wp_check_password().
Code that otherwise directly interacts with the hashed value of an application password, password reset key, personal data request key, or the recovery mode key. If such hashes are validated directly, this should be done via the new wp_verify_fast_hash() function.
Any plugin that overwrites the pluggable wp_hash_password() and wp_check_password() functions. Unless these functions specifically implement another hashing algorithm, they can be removed in order to allow the bcrypt implementation in 6.8 to take effect.
Alternative authentication mechanisms such as single sign-on (SSO), social login, or one-time login are unlikely to be affected by this change, however you should still verify whether your specific implementation includes any handling of password hashes or security keys. Multi-factor (MFA and 2FA) implementations are also unlikely to be affected by this change.
What about Argon2?
Servers that support Argon2 can enable its usage with this single line of code in WordPress 6.8 and later:
If necessary, the password_algos() function should be used to first check for argon2id support. Unfortunately it’s not possible to rely on Argon2 being available on all servers because it requires both libargon2 to be available on the server and for PHP to be built with Argon2 support enabled. The sodium_compat library does not provide an implementation of Argon2.
Acknowledgements
We can’t pretend that switching to bcrypt for user-generated passwords is a recent proposal. Ideally the switch would have been made back when the increase to the minimum supported version of PHP facilitated this change. However, this change has now been made and it helps future-proof further improvements to password hashing, including increases to the bcrypt cost in newer versions of PHP.
Many thanks go to the Roots team for maintaining their bcrypt password hashing package for WordPress as well as the many contributors on the TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. tickets and GitHubGitHubGitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ pull requests.
User passwords are stored as a hash in the wp_users.user_pass field in the database.
Application passwords are stored as a hash in a JSONJSONJSON, 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. serialized object in the wp_usermeta table using the _application_passwords key.
User password reset keys are stored as a hash in the wp_users.user_activation_key field in the database.
Personal data request keys are stored as a hash in the wp_posts.post_password field in the database against the post that represents the personal data request.
The recovery mode key is stored as a hash in the recovery_keys option in the wp_options database table.
Earlier in the 6.7 cycle, @hellofromtonya and @jrf made a number of commits to get the codebase ready for PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher 8.4.
Here are a few of the most notable, starting with PR #7376:
Fix trigger_error() with E_USER_ERROR deprecation in wp_trigger_error().
PHP 8.4 deprecates the use of trigger_errror() with E_USER_ERROR as the error level, because this way of creating a Fatal Error brings its own set of pitfalls (finally blocks not executing, destructors not executing). instead, the recommendation is to use an exception or do a hard exit.
WP has its own wp_trigger_error() function, which under the hood calls trigger_error(). If the WP version of the function passes E_USER_ERROR as the $error_level, it too will hit the PHP 8.4 deprecation.
Now, there were basically three options:
Silence the deprecation until PHP 9.0 and solve this properly then. But that wouldn’t even really buy time, let alone solve the problem. That’s because before PHP 8.0, error silencing goes too far, applying to all errors. And starting with PHP 8.0, silencing doesn’t apply to fatal errors.
Use exit($status) when wp_trigger_error() is called with E_USER_ERROR. But that would make the code untestable. It would also disable handling of these errors with custom error handlers. Neither of those are acceptable outcomes.
Throw an exception when wp_trigger_error() is called with E_USER_ERROR. This is a fairly elegant solution, and it carries the least BC-breaking impact. There is some chance the error gets caught in a try-catch, but that’s not actually a bad thing. It’s likely to only happen for errors that can be worked around—and that’s actually an unexpected bonus.
This commit implements the third option, which:
Introduces a new WP_Exception class.
Starts using WP_Exception in the wp_trigger_error() function when the $error_level is set to E_USER_ERROR.
This change is covered by pre-existing tests, which have been updated to expect the exception instead of a PHP error.
Why not use WP_Error?
Well, for one, this would lead to completely different behavior (BC).
WP_Error doesn’t extend Exception. So the program would not stop. Instead, it would keep running, which is a much bigger breaking change and carries security risks. WP_Error also doesn’t natively trigger displaying/logging of the error message, so it would still need an exit with the error message, bringing us back to point 2 above.
Introducing WP_Exception delivers (essentially) the same behavior. It retains the fatal error and error message displaying/logging behaviors. Plus it introduces a base Exception class, which future exception classes can extend over time.
Several other commits, from #62061, also help get the codebase ready for 8.4. You can find them after an exhaustive introduction to the changes coming to the new PHP.
Here’s the list, by GH pull request:
PR #7369 WP_HTML_Processor: fix implicitly nullable parameter [1] in the WP_HTML_Processor class.
PR #7370fixes the deprecation of xml_set_object() for the TestXMLParser helper utility.
PR #7371fixes the same deprecation for the IXR_Message::parse() method.
PR #7372 fixes the deprecation for the AtomParser::parse() method.
PR #7373 fixes it for the MagpieRSS::__construct() method.
PR #7374replaces the call to the deprecated mysqli_ping() with the DO 1 query.
PR #7375adds a simple test for the Text_Diff::_check() method—and fixes the bugbugA 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. that test finds!
PR #7379Build/Test Tools: Enable running all the tests on PHP 8.4 once there’s a stable release of Xdebug 3.4.0.
Props @hellofromtonya for the commit message that formed the basis of this dev notedev noteEach 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. and to @peterwilsoncc for review and collaboration.
Determining whether a translationtranslationThe process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. exists
Sometimes it can be useful to know whether a translation already exists for in memory without having to first load the translation for the given text domain. The new has_translation() function allows for exactly that.
Sending emails in the adminadmin(and super admin)’s localeLocaleA locale is a combination of language and regional dialect. Usually locales correspond to countries, as is the case with Portuguese (Portugal) and Portuguese (Brazil). Other examples of locales include Canadian English and U.S. English.
Back in version 4.7, WordPress added the ability for users to set their preferred locale. When sending emails to a user, they are always sent in that locale, and everyone else receives the email in the site’s locale.
Now, WordPress 6.7 is going a step further: every time an email is sent to the administrator email address (admin_email), WordPress checks if a user with the same email address exists. If so, the email is sent in that user’s locale.
WordPress now warns developers if they are loading translations too early in a pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party or theme, before the current user is known. Existing functions like load_plugin_textdomain() and load_theme_textdomain() were updated to defer the actual loading to the existing just-in-time translation logic in coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress.. This reduces the likelihood of triggering the warning, and even improves performance in some situations by avoiding loading translations if they are not needed on a given page.
Reminder: if your plugin or theme is hosted on WordPress.orgWordPress.orgThe community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ and is still using load_*_textdomain(), you can remove this call. Since WordPress 4.6, plugins and themes no longer need load_plugin_textdomain() or load_theme_textdomain(). WordPress automatically loads the translations for you when needed. If you still support older WordPress versions or do not host your plugin/theme on WordPress.org, move the function call to a later hook such as init.
When attempting to load translations before after_setup_theme or init, WordPress tries to load the current user earlier than usual, without giving other plugins a chance to potentially hook into the process. It also prevents any plugins from filtering translation calls, e.g. for switching the locale or file location. Hence the addition of this warning to call out this unexpected behavior.
Your plugin might be _doing_it_wrong() if you for example directly call get_plugin_data() (which attempts to load translations by default) or __() without waiting for the init hook. Here is a common example that was found in an actual plugin that was fixed:
If you do not explicitly set $translate set to false when calling get_plugin_data(), the function translates the plugin metadata by default. Since this plugin just needs the version number, there is no need for translating any of the other fields.
Another example:
/**
* Plugin Name: Awesome Plugin
*/
class My_Awesome_Plugin {
public $name;
public function __construct() {
// This triggers just-in-time translation loading
$this->name = __( 'My Awesome Plugin', 'my-awesome-plugin' );
// ... do something
}
}
// This immediately instantiates the class, way before `init`.
$myplugin = new My_Awesome_Plugin();
Here, a class is immediately instantiated in the main plugin file, and code within the class constructor uses a translation function. This can be avoided by deferring the class instantiation until after init, or deferring the translation call until later when it is actually needed.
If your plugin is affected by this warning, you can use code like follows to find out the code path that triggers it:
add_action(
'doing_it_wrong_run',
static function ( $function_name ) {
if ( '_load_textdomain_just_in_time' === $function_name ) {
debug_print_backtrace();
}
}
);
Developer tools such as Query Monitor are also helpful in situations like this.
WordPress 6.7 introduces various improvements to the BlockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. Bindings APIAPIAn 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. and the built-in post metaMetaMeta 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. source, including a default UIUIUser interface and the beginnings of a public editor API.
For an introduction to Block Bindings, first introduced in WordPress 6.5, see the prior dev note.
New Block Bindings UI
Compatible blocks — which currently include Heading, Paragraph, Image, and Button — have received a new default UI for viewing bindings.
Called Attributes, you can find the new tool panel in block settings whenever a compatible block is selected in either the post or site editor.
The panel shows active bindings on the current block. If there are any post meta available, the panel is also interactive, allowing you to bind attributes to those custom fields via the built-in post meta block bindings source.
Currently, there are two limitations to the panel:
It will not allow users to bind attributes to custom sources just yet.
Bindings to custom sources, which can be added via the code editor or other programmatic means, will still display in the panel — they just can’t be connected via the UI for the moment in WordPress 6.7.
A flexible API for connecting custom sources to the Attributes panel is currently under development and is planned for public release in the future.
For now, the rollout of that API has started with the built-in post meta source to allow time for gathering feedback.
For each attribute, the panel will only show custom fields that match its data type. For example, an attribute of type string or rich-text can only be connected to a custom fieldCustom FieldCustom Field, also referred to as post meta, is a feature in WordPress. It allows users to add additional information when writing a post, eg contributors’ names, auth. WordPress stores this information as metadata. Users can display this meta data by using template tags in their WordPress themes. of type string, and an attribute of number can only be connected to another number.
New Post Meta Label Attribute
To improve how custom fields appear in the editor UI, a new label attribute has been created for post meta, which can be defined during registration:
If specified, the label will render in place of the meta key in the Attributes panel — in this example, the label would replace movie_director. The label will also render under certain circumstances in other parts of the editor, including as a placeholder for Rich Text if a block is bound to the post meta source and a default value is undefined.
Usage In Custom Post Templates
One of the primary use cases for Block Bindings is to assist in creating templates for custom post types. Given a custom post typeCustom Post TypeWordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. called movie, for example, one can define how custom fields for that post type will render, such as via connected images, headings, paragraphs, and buttons.
Here is an example of how one could use connected blocks to create a layout:
One can override the content in connected blocks for each instance of the custom post type, a much simpler and more flexible way of creating layouts than in the past — all without needing to create custom blocks.
Default Permissions
Accompanying this UI is a new canUpdateBlockBindings editor setting, used to determine whether the UI is interactive for users or not.
By default, this editor setting is set to a new edit_block_binding capability, which maps to a user’s ability to either:
Edit the post type (in the post editor), or
Edit the theme options (in the site editor)
This means that the setting is by default set to true for administrators, and false for other users.
This default setting can be overridden using the block_editor_settings_allfilterFilterFilters 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. and modifying $editor_settings['canUpdateBlockBindings'] as follows:
Several functions have been exposed to enable the use of block bindings in the editor.
Registration API
Source Bootstrapping
As part of the new editor API, Block Bindings will automatically register custom sources defined on the server with bootstrapped values in the editor. This will allow existing sources registered using just the server APIs to render in the UI.
This means that any sources already registered using the server APIs, available since 6.5, will appear in the UI, at least minimally, without any action required.
For example, given the following server registration and block markup…
…the source will get registered in the editor with the source’s name my-plugin/post-attributes, label, and uses_context values. This is enough for the UI to render as follows:
In this case, however, the bound paragraph in the block canvas will simply show the source label and will not be dynamic. Further customization of the editor experience requires using the new editor registration functions, detailed in the next section.
Editor Registration
The following functions have been exposed to allow customization of the editor experience:
registerBlockBindingsSource: Registers a source on the client (using this function will override the bootstrapped registration).
unregisterBlockBindingsSource: Unregisters an existing source.
getBlockBindingsSource: Gets a specific registered source and its properties.
getBlockBindingsSources: Gets all the registered sources in the client.
These are based on other registration APIs like block types, block variations, or block collections.
Source Properties
Registered sources in the client can include the following properties:
name: The unique and machine-readable name.
label: Human-readable label. Will overwrite preexisting label if it has already been registered on the server.
usesContext: Array of context needed by the source only in the editor. Will be merged with existing uses_context if it has already been registered on the server.
getValues: Function to get the values from the source. It receives select, clientId, context, and the block bindings created for that specific source. It must return an object with attribute: value. Similar to getBlockAttributes.
setValues: Function to update multiple values connected to the source. It receives select, clientId, dispatch, context, and the block bindings created for that specific source, including the new value. Similar to updateBlockAttributes.
canUserEditValue: Function to let the editor know if the block attribute connected should be editable or not. It receives select, context, and the source arguments.
Example Usages
Register a Block Bindings Source
Building on the example server registration, use the following JavaScriptJavaScriptJavaScript 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/. to register in the editor by enqueuing on the enqueue_block_editor_assets hook:
Note: If desired, sources may be registered only on the client and not on the server at all. This could be useful for creating forms in the adminadmin(and super admin), or otherwise using bindings to interact with other parts of WordPress, or other dynamic data.
Block Bindings Utils
The useBlockBindingsUtils hook returns helper functions to modify the metadata.bindings attribute. The hook accepts an optional clientId argument. If the clientId is not specified, the helper functions will execute in the current block edit context.
Right now, the helpers include:
updateBlockBindings: This works similarly to updateBlockAttributes. It can be used to create, update, or remove specific connections.
removeAllBlockBindings: This is used to remove all existing connections in a block.
Example usage
import { useBlockBindingsUtils } from '@wordpress/block-editor';
const { updateBlockBindings, removeAllBlockBindings } = useBlockBindingsUtils();
// Updates bindings for url and alt attributes.
updateBlockBindings( {
url: {
source: 'core/post-meta',
args: {
key: 'url_custom_field',
},
},
alt: {
source: 'core/post-meta',
args: {
key: 'alt_custom_field',
},
},
} );
// Removes all bindings set for the block.
removeAllBlockBindings();
Used internally by the default UI for the post meta source and pattern overrides, these utils can be useful in building custom UI for other sources.
A block_bindings_source_value filter has been introduced to allow for overriding of the value returned by a source in a bound block. It takes the following arguments:
value: Value returned by the source.
name: Name of the source.
source_args: Arguments passed to the source.
block_instance: The bound block.
attribute_name: The connected attribute in the bound block.
The developers behind Block Bindings are always happy to hear feedback. Please feel free to share bugs, feature requests, or other thoughts by creating issues on GithubGitHubGitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ or leaving a comment on this post.
Anyone can also follow and comment on Block Bindings development via the latest iteration, which is posted in the Block Bindings tracking issue at the beginning of each release cycle. Be sure to subscribe to the tracking issue for updates!
Lastly, if you’d like to help shape the roadmap for Block Bindings by sharing your use cases, feel free to post in Block Bindings discussions.
Zoom Out in WordPress 6.7, introduces a new way to easily create and edit content using Patterns rather than lower-level, individual blocks.
Accessible via a toggle in the editor toolbar, when activated the canvas will “zoom out” providing users with a high level view of the content currently being edited. The inserter also automatically enables this new feature when the patterns tab is activated, allowing users to quickly and easily build and/or edit their Page or Template using pre-configured Patterns.
Note that whilst in this mode, blocks outside the “main content” of the current post will be non-editable. This allows users to focus on easily dealing with larger areas of content.
Theme Compatibility
To facilitate this feature, the Editor will attempt to detect the blockBlockBlock 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. which is acting as the “main content” of the current post type. This is achieved via a simple algorithm which optimises for detecting the Post Content (core/post-content) block, falling back to a Group with a tagName of main (i.e. the <main>HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. element).
To maximise compatibility with this mode, Theme authors should update their templates to ensure their “main content” is wrapped with a Group block whose tagName attribute is configured as main. This can be found in the block’s sidebarSidebarA 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. controls under Advanced. We recommend using a core/group as it is the most generic and flexible “sectioning element” in the editor.
Decoupling of Zoom Out mode from “zooming” the canvas
As part of this effort, contributors have also elected to decouple the scaling of the Editor canvas from the “Zoom Out” editor mode. This is largely in anticipation of future efforts around simplifying the editing experience. As a result, invoking zoom-out editor mode will not longer automatically scale the Editor canvas.
Since the introduction of blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. themes, theme authors have been able to create custom block templates. However, this possibility was limited to themes, leaving plugins without a straightforward way to register their own templates. To achieve similar functionality, plugins had to resort to complex methods, including hooking into multiple PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher filters, manually creating WP_Block_Template objects, and replicating internal WordPress logic.
WordPress 6.7 introduces a new APIAPIAn 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. that will significantly simplify the process for plugins to register their own block templates. To enable this, two new functions have been introduced: register_block_template() for registering a block template and unregister_block_template() for unregistering it.
register_block_template( string $template_name, $args = array() ) accepts two parameters, that define how the template is registered:
$template_name: The name of the template in the form of plugin_uri//template_name (note that this requires a double //).
$args: An array of arguments for defining the template:
title: An internationalized title for the template.
description: An internationalized description of the template.
content: The default content (block markup) for the template when rendered in the editor or on the front end.
post_types: An array of post type slugs to make available to users as per-post custom templates.
For example, a pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party can register a template with the following snippet:
Plugins can also override templates from the WordPress template hierarchy, such as the archive page of a custom post typeCustom Post TypeWordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. or a specific author page.
Theme templates take priority over plugin-registered templates, allowing themes to override specific plugin templates just as they can with WordPress templates.
Currently, this API is limited to block templates and does not allow the registration of block template parts.
You can read more about this new feature in the following links:
Props to @aljullu for writing this dev notedev noteEach 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.. And thanks to @fabiankaegy for reviewing
In this post, you will find dev notesdev noteEach 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 6.7.
Table of contents
Stabilized Role Property for blockBlockBlock 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. Attributes
As of WordPress 6.7 the __experimentalRole block attribute property has been stablised as role.
This property is part of the block.json specification and can be applied to any attribute of a block to designate it as being of a particular conceptual type.
Depending on the chosen type, the attribute may then be handled differently at both an APIAPIAn 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. level and/or within the Editor’s user interface.
The available types are:
content
this designates the attribute as being user-editable content.
blocks with attributes marked as content may be enabled for privileged editing in special circumstances such as when making edits to content in partially synced Patterns.
local
marks the given attribute as being “temporary” and non-persistable.
for example, the image block utilises a blob attribute marked as local to store a temporary URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org created whilst an image is uploading.
Changes to Selectors and API functions
As part of this effort some selectors and API functions have received changes:
__experimentalHasContentRoleAttribute selector from the @wordpress/block-editor package has been deprecated and made private.
__experimentalGetBlockAttributesNamesByRole API function from the @wordpress/blocks package has been stablized as getBlockAttributesNamesByRole.
Props to @get_dave for writing the dev notedev noteEach 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..
Heading level curation
In WordPress 6.7, coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. blocks with a heading level dropdown now support the new levelOptions attribute, which includes the Heading, Site Title, Site Tagline, Query Title, Post Title, and Comments Title blocks. The levelOptions attribute accepts an array of numbers corresponding to heading levels, where 1 represents H1, 2 represents H2, and so on.
This attribute allows developers to specify which heading levels should appear in the dropdown UIUIUser interface, providing a lightweight curation method that does not require block deprecations. Any existing heading levels are preserved in the markup, while levelOptions only affects the UI display.
You can apply this attribute directly in the block markup, a technique that will be commonly used in block templates, template parts, and patterns. For example, the following markup disables H1, H2, and H6 in the Heading block by setting "levelOptions":[3,4,5].
You can also use block filters to set the default value of this attribute globally or for specific blocks. The example below disables H1, H2, and H6 for all Heading blocks. You can further customize this by restricting certain heading levels based on conditions like user capabilities.
Blocks with “contentOnly” locking are no longer transformable
In 6.7, the block transformation menu and block variations selector are not available for blocks with “contentOnly” content locking.
For example, a Group Block that has “contentOnly” locking cannot be transformed to a Columns Block, or switched to a Group variation such as Grid, Row or Stack. Transforming to other blocks or block variations has the potential to mutate the entire block structure, including its internal content.
The purpose of “contentOnly” is to allow editing of a block’s content, for example, its internal headings, text or images.
Support for async actions and filters in @wordpress/hooks
The @wordpress/hooks package has a couple of new functions for running async actions and filters, allowing pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors to conveniently register async (promise-based) handlers and make sure that they are run in series, one after another, waiting until the previous async handler finishes.
You can register an async function as an action or a filterFilterFilters 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. handler:
In the filter handler, the value is always a synchronous value (not a promise) and the handler function returns a promise that resolves to an updated value.
Then you can run the filter with a newly introduced applyFiltersAsync function:
and similarly you can also run an action with the new doActionAsync function:
import { doActionAsync } from '@wordpress/hooks';
await doActionAsync( 'action' );
The runner functions make sure that handlers are run after each other, in a series. And that when a handler throws an error (or returns a rejected promise), the whole run is aborted and further handlers are not called. The error is propagated and becomes the result of the entire applyFiltersAsync/doActionAsync call.
New filters to customize and extend behavior of post save
There are two new hooksHooksIn 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. (one filter and one action) that allow plugin authors to customize and extend what happens when a post is being saved.
First, there is the (async) editor.preSavePost filter that receives two arguments:
edits is an object that contains the id of the saved post and the modified attributes. The filter can modify the edits and it will be this modified object that will be sent to the server as the payload of the save POST request. The filter can also abort the save, e.g., when some custom validation fails, by throwing an error or returning a rejected promise.
options is a read-only second argument that contains an isAutosave (boolean) field that lets the filter distinguish between regular saves and autosaves, and also an isPreview field that indicated whether the saved post is a draft intended to be previewed.
The handler can be async, as the filter is being applied using the new applyFiltersAsync function:
The second new hook is the (async) editor.savePost action which is run after the post is saved and lets you perform additional work after the save. For example, the GutenbergGutenbergThe 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/ post editor itself uses this action to save legacy metaboxes for the post. This action receives one argument, the options object, the same one as the editor.preSavePost action also receives.
The new useEvent utility creates a stable callback that has access to the latest state (as opposed to a useCallback call with an empty dependency array). This is useful to “untrack” dependencies in a callback that is called within event handlers or effects. It cannot be called at render time.
This is a common pattern in React, and it’s even being considered as a core React feature (see the RFC). More context can be found in this popular issue in the React repository.
Here’s an example:
function Component( props ) {
const onClick = useEvent( props.onClick );
useEffect( () => {
onClick();
// Won't trigger the effect again when `props.onClick` is updated.
}, [ onClick ] );
// Won't re-render `Button` when `props.onClick` is updated (if `Button` is
// wrapped in `React.memo`).
return <Button onClick={ onClick } />;
}
Props to @daniguardiola for writing the dev note.
New useResizeObserver hook in @wordpress/compose
The new API and behavior of useResizeObserver is meant as a thin wrapper for the browser-native ResizeObserver API, which enables more use cases and better composition. The previous API is still supported, though it is considered legacy and deprecated.
const setElement = useResizeObserver(
( resizeObserverEntries ) => console.log( resizeObserverEntries ),
{ box: 'border-box' }
);
<div ref={ setElement } />;
// The setter can be used in other ways, for example:
useLayoutEffect( () => {
setElement( document.querySelector( `data-element-id="${ elementId }"` ) );
}, [ elementId ] );
Props to @daniguardiola for writing the dev note.
New useStyleOverride hook in @wordpress/block-editor
wp.blockEditor.useStyleOverride is a new editor API that can be used to add content styling (renders inside the content iframeiframeiFrame 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.).
import { useStyleOverride } from '@wordpress/block-editor';
function SomeComponent() {
useStyleOverride( { css: 'p{color:red}' } );
return (...);
}
General Editor UI/UXUXUser experience improvements
Updates to the Query LoopLoopThe 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
WordPress 6.7 brings a number of improvements and changes to the Query Loop block.
The controls to set how many items to display, the offset and max number of pages, have been moved from the block toolbar to the Inspector Sidebar. This change standardizes the location of all of the query controls in the UI, making it much easier to find them.
Query Loop blocks that are inserted into single page, post, or custom post typeCustom Post TypeWordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. now no longer display the Query Type control and defaults to querying posts. When using the block on templates, the Posts per page setting is now inherited by the block. A new filter was added to allow filtering by Post Formats and the Posts List variation was removed due to some inconsistencies in how the block would receive defaults.
Props to @welcher for writing the dev note.
New Font Size Presets UI
A new UI feature has been introduced in the Global Styles section of the editor, allowing users to add, edit, and remove font size presets.
A font size preset is a predefined font size that can be reused throughout the site via the font size picker. This enhancementenhancementEnhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. provides a more user-friendly way to manage font size options, which were previously only accessible via the manual edition of theme.jsonJSONJSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. file. Users can now modify preset names, base sizes, enable or disable the default fluid behavior, and customize the minimum and maximum values for fluid font size presets directly from the UI.
To access this interface, navigate to the Styles sidebarSidebarA 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., then go to Typography → Font Sizes.
Props to @mmaattiiaass for writing the dev note.
New ‘human-diff’ Date Format Option
A new date format option has been introduced for the Post Date and Comment Date blocks, allowing users to display dates in a human-readable, relative format.
The human-diff format presents dates in a more intuitive way, such as 12 hours ago, 2 days ago, or a month ago. This enhancement provides a more user-friendly way to display date information, which can improve readability and engagement for readers.
To use this new format, users can select the option that displays an example of the relative time format (e.g., “2 years ago”) from the Choose a format dropdown in the block settings panel for both the Post Date and Comment Date blocks. The feature utilizes WordPress’s built-in human_time_diff() function to calculate and display the relative time difference.
To access this option:
Insert a Post Date or Comment Date block in your post or page.
In the block’s settings panel, locate the Choose a format option.
Click on the dropdown to reveal various date format options.
Select the option that shows an example of the relative time format (e.g., “2 years ago”).
New preference to disable the “Choose a pattern” modal when adding pages
A pattern selector modal appears when creating pages. The modal will reappear so long as the the page content is empty.
In 6.7, this feature can be toggled on and off through a new “Show starter patterns” toggle switch, located in the “Interface” section of editor preferences.
New style engine util for compiling CSSCSSCascading Style Sheets. custom vars
WordPress 6.7 introduces a new public utility, getCSSValueFromRawStyle(), exported from the style engine package. This function is useful for processing or manipulating Global Styles data, handling both standard CSS and preset string values.
Example usage:
// Example 1: Standard CSS remains unchanged.
getCSSValueFromRawStyle('min(40%, 400px)');
// Returns: 'min(40%, 400px)'
// Example 2: CSS variable for preset color.
getCSSValueFromRawStyle('var:preset|color|wordpress-blue');
// Returns: 'var(--wp--preset--color--wordpress-blue)'
Media & Text block now always uses img tagtagA 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.) instead of background image
As of #64981, the Media & Text block now uses an img element instead of using CSS background-image when the “Crop image to fill” option is enabled, removing the last usage of background-image in this block. This means that, when rendering the post, all the usual performance benefits of using image elements will now be applied, such as having the image load lazily when appropriate, and letting the browser choose the most appropriate image size from the list of generated sizes.
block.json: variations field can now be set to name of PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher file that generates block variations
Previously, the variations field in a block.json file could be used to provide a static list of the block’s variations (i.e., an array). Alternatively, the block’s variation_callback could be set during server-side block registration to point to a PHP function to generate those variations. As of WordPress 6.7, it is also possible to set the variations field to a string, which will then be interpreted as the filename of a PHP file that generates the variations (akin to how the render field works):
Decreased spacing between Block Inspector controls
(This dev note was added on October 24th.)
The standard spacing between controls in the Block Inspector has been reduced to 16px (was previously 24px).
Extenders will likely see the majority of their controls adhereing automatically to the new spacing, due to a Block Inspector style setting bottom margins on all components built with BaseControl. However, if you have a control that is not built with BaseControl, or have overridden the bottom margin styles for whatever reason, you may want to adjust your custom spacing so it is consistent with the new 16px spacing.
WordPress 6.7 adds sizes=”auto” for lazy-loaded images. This feature, which was recently added to the HTML specification, allows the browser to use the rendered layout width of the image when selecting a source from the srcset list, since lazy loaded images don’t load until after the layout is known.
Background
Responsive image attributes, srcset and sizes were added in WordPress 4.4. Quoting the dev notedev noteEach 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. from that time:
To help browsers select the best image from the source set list, we also include a default sizes attribute that is equivalent to (max-width: {{image-width}}px) 100vw, {{image-width}}px. While this default will work out of the box for a majority of sites, themes should customize the default sizes attribute as needed using the wp_calculate_image_sizesfilterFilterFilters 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..
Setting a default sizes value is important when choosing the right file to fetch from srcset, because it tells the browser what the intended layout of an image will be before the layout is known. Without any value, browsers will use the default 100vw value and assume the image is meant to fill the entire width of the viewport, resulting in many wasted bytes. The default value that has shipped with WordPress for many years ensures that the image layout is constrained by its width attribute. This helps, but in many cases is still not correct, since an image is likely layout constrained by the content width, or any blocks that they are nested within.
Even though it is encouraged for themes to supply a more accurate sizes attribute value using the wp_calculate_image_sizes filter, doing so is challenging. Now that browsers are able to automatically apply the rendered layout to sizes for lazy-loaded images, the sizes value will be 100% correct, resulting in many fewer wasted bytes.
Implementation details
The HTML specification allows for lazy loaded images to omit sizes, explicitly set sizes=”auto”, or set sizes to a string that starts with "auto," followed by a valid source size list. In order to implement this as a progressive enhancementenhancementEnhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. for browsers already supporting this feature, WordPress will prepend auto to the sizes attribute of content images during wp_filter_content_tags() and any image markup generated by wp_get_attachment_image(). This will cause browsers that don’t support the new auto value to fall back to the previous sizes list.
WordPress will only add auto to the sizes value if the image includes loading=”lazy”. Otherwise, browsers that support sizes=auto will fail to validate the sizes value and apply the default value of 100vw, which will cause larger than needed images to be selected from the srcset attribute. Any custom implementations that change the loading value of images after WordPress generates the markup should use the new wp_img_tag_add_auto_sizes() function to correct the sizes attribute.
Functions added
wp_img_tag_add_auto_sizes – adds auto sizes to an HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers.img string.
wp_sizes_attribute_includes_valid_auto – tests whether auto already exists on an image to ensure it’s not added more than once.
After an effort to iframe the post editor, the presence of metaMetaMeta 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 was a holdout condition that kept the editor content from loading in an iframeiframeiFrame 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. and made these benefits of the iframe unavailable:
Isolation of blockBlockBlock 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 CSSCSSCascading Style Sheets. from the editor UIUIUser interface
Accuracy of media queries and viewport relative CSS units
Those benefits are important to support CSS reuse across the editor and front-end and generally ease block and theme development. It’s been an ongoing effort to bring them to the Post editor even when meta boxes are present yet it has taken afewattempts to determine how to adapt the interface to separate the meta boxes from the post content.
Now a split view is implemented that supports both editor content and meta boxes being visible together. This change ensures consistent WYSIWYGWhat You See Is What You GetWhat You See Is What You Get. Most commonly used in relation to editors, where changes made in edit mode reflect exactly as they will translate to the published page. experience between the Editor and front-end views. Additionally, it makes the meta boxes are more readily available than before and allows visually referencing any part of the post content while working with any meta box or vice versa.
Remaining exception to the iframe
For now, the last condition which prevents the iframe from always being used is whether any blocks are registered with their apiVersion less than 3. Yet even this condition may be removed in a future release and it already has an exception if your site uses the GutenbergGutenbergThe 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/pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and a block based theme is active.
Edge cases and compatibility
Developers of plugins that add meta boxes should be wary of two things. One, the meta box container now clips overflowing elements so some popover-like UI such as dropdown menus will be cut off if they extend upward from the meta box container. However, if they’re rendered into a part of the DOM outside the container this won’t be an issue. Two, if your plugin also adds any rich text formats with editing UI that’s anchored to the text selection then their implementation has to be compatible with the iframe. This isn’t a new requirement but may have been overlooked for plugins only extending the Post editor.
Overflow clipping
To ensure this isn’t an issue any popover-like UI can be made to open downward in the meta box or by rendering the popover into a part of the DOM that is not within the meta box container. The latter, for instance, is how the Popover, Dropdown and DropDownMenu components from @wordpress/components work by default and using them will ensure there is no clipping even if the UI extends beyond the top of the meta box container.
Rich Text Format UI anchoring
This is may only be of concern if your plugin implemented custom code to anchor or position the UI. If your plugin is already using the recommended useAnchor hook available from @wordpress/rich-text everything should just work. In case it’s not, you can reference Gutenberg’s own link editing UI component for a canonical example of its usage.
You must be logged in to post a comment.