Site-wide background images in WordPress 6.6

In WordPress 6.6 you can define site-wide background images 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. and the Site Editor.

A “site-wide” background image is one whose value is set on the body element using the background-image CSSCSS Cascading Style Sheets. property, and, therefore, appears on every page of a site.

An example might be a photo that stretches with the window size, or a repeating pattern background.

To customize how background images appear, WordPress 6.6 supports the following background style properties:

  • background position
  • background size
  • background repeat

Usage

In theme.json

In theme.json, site-wide background images and their properties are defined under "styles.background".

For example, as a single image URI in styles.background.backgroundImage.url:

{
	"styles": {
		"background": {
			"backgroundImage": {
				"url": "http://path.to/some/image.png"
			},
			"backgroundSize": "cover"
		}
	}
}

For the above, WordPress will automatically wrap the image in the CSS url() function.

styles.background.backgroundImage also accepts string values, which can be any valid CSS value for background-image :

{
	"styles": {
		"background": {
			"backgroundImage": "url(http://path.to/some/image.png)",
			"backgroundPosition": "center"
		}
	}
}

The above examples use absolute paths to image files. Such files would need to be hosted and maintained.

Most likely, theme developers will want to define background images using paths to a theme’s own assets. This ensures that the theme is self-contained and portable.

Relative paths to theme assets are defined using the file:./ prefix:

{
	"styles": {
		"background": {
			"backgroundImage": {
				"url": "file:./assets/my-theme-background.jpg"
			},
			"backgroundSize": "cover"
		}
	}
}

Paths are resolved on the backend using get_theme_file_uri.

Paths defined this way must be relative to the theme root, regardless of where the theme.json sits in your theme’s directory. This follows an existing pattern for web fonts.

Despite the dot in file:./, the special symbols dot (.) and double dot (..) for directory navigation are not supported in theme.json relative paths. This means, for example, that theme style variation files, which reside under the style/ directory, would use the same path as the theme’s main theme.json.

An issue exists to make the syntax more consistent.

In the Site Editor

Background images can be also be uploaded, and their properties tweaked through the Site Editor’s styles panel.

In WordPress 6.6, background image controls are located under Styles > Layout.

The styles panel navigation is undergoing review however, so in upcoming versions the location may change.

As well as setting new background images, it’s possible to “remove” a theme’s default background image in the Site Editor.

Relative paths to any images in theme.json are resolved on the backend, and are sent in the _links array of Global Styles REST responses. The Editor uses the resolved values to generate theme CSS in the client.

Limitations

In WordPress 6.6, the ability to define background images in theme.json exists only for top-level styles. Top-level styles apply to the body element. An open PR aims to also enable the feature at 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. level in the next WordPress release.

Work is also underway to:

  • add support for fixed images, using the background-attachment CSS property.
  • avoid conflicts between gradient backgrounds, whose values are currently set to the background property, and background-image. The proposal is that gradient backgrounds will also be set to background-image, and, where both an image and a gradient are defined, their values are merged .

Backwards compatibility

WordPress already has support for custom site-wide background images in the Customizer. The theme.json variant will not affect themes that have enabled this feature.

Background images added in the CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. take precedence over those set in theme.json or in the Site Editor.

An ongoing discussion seeks to harmonize the two features.

What’s next

Progress on upcoming work is tracked on Background Image block support follow-up tasks.

Props to @andrewserong and @juanmaguitar for review

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

Theme.json version 3

The theme.jsonJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. version is incremented whenever a breaking change would need to be made to the 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.. This allows consumers to opt-in to the breaking change by updating the version. Older theme.json versions will always be supported in the latest versions of WordPress.

Upgrading to version 3 is recommended when your minimum supported WordPress version reaches 6.6. See the theme.json reference for more info on migrationMigration Moving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies..

Why does my code editor tell me to update to version 3?

This is probably because you are using the wrong version of the theme.json schema. The theme.json schema has different versions that correspond to WordPress releases and a 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. version that includes all the latest changes from the GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party.

The WordPress release versions of the schema follow the pattern: http://schemas.wp.org/wp/x.x/theme.json. Use the version that matches your minimum supported WordPress version. For example, use https://schemas.wp.org/wp/6.5/theme.json if the minimum supported WordPress version for your theme is WordPress 6.5.

If you update the schema reference in your theme.json file to match the version that you are using, then the code editor will be able to tell you which version of theme.json you should be using as well as the features that are available in that version of WordPress.

Breaking changes in version 3

Starting with theme.json version 3 the default behavior for using the same slugs as the default fontSizes and spacingSizes presets has been changed to match how other theme.json presets work: from always overriding the default presets to requiring defaultFontSizes or defaultSpacingSizes to be false in order to override the default presets.

Default font sizes

settings.typography.defaultFontSizes is a new option in theme.json v3. It controls whether the coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. provided default settings.typography.fontSizes presets are shown and used.

The default fontSizes presets’ slugs are: small, medium, large, x-large, and xx-large.

  • When defaultFontSizes is true it will show the default font sizes in the editor and prevent the theme from creating presets using the default slugs.
  • When defaultFontSizes is false it will hide the default font sizes in the editor and allow the theme to use the default slugs.

For blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. themes defaultFontSizes is true by default. This is consistent with how other default* options work such as settings.color.defaultPalette.

For classic themes there is a new theme support default-font-sizes which is also true by default. However, unlike block themes, it is set to false when editor-font-sizes theme support is defined.

In theme.json v2, the default font sizes were only shown when theme sizes were not defined. A theme providing font sizes with the same slugs as the defaults would always override the defaults.

To keep behavior similar to v2 with a v3 theme.json:

  • If you do not have any fontSizes defined, defaultFontSizes can be left out or set to true.
  • If you have some fontSizes defined, set defaultFontSizes to false.
--- theme.json v2
+++ theme.json v3
@@ -1,24 +1,25 @@
 {
-	"version": 2,
+	"version": 3,
 	"settings": {
 		"typography": {
+			"defaultFontSizes": false,
 			"fontSizes": [
 				{
 					"name": "Small",
 					"slug": "small",
 					"size": "10px"
 				},
 				{
 					"name": "Medium",
 					"slug": "medium",
 					"size": "14px"
 				},
 				{
 					"name": "Large",
 					"slug": "large",
 					"size": "20px"
 				}
 			]
 		}
 	}
 }

Default spacing sizes

settings.spacing.defaultSpacingSizes is a new option in theme.json v3. It controls whether the core provided default settings.spacing.spacingSizes presets are shown and used.

The default spacingSizes presets’ slugs are: 20, 30, 40, 50, 60, 70, and 80.

  • When defaultSpacingSizes is true it will show the default spacing sizes in the editor and prevent the theme from creating presets using the default slugs.
  • When defaultSpacingSizes is false it will hide the default spacing sizes in the editor and allow the theme to use the default slugs.

defaultSpacingSizes is true by default. This is consistent with how other default* options work such as settings.color.defaultPalette.

For classic themes there is a new theme support default-spacing-sizes which is also true by default. However, unlike block themes, it is set to false when editor-spacing-sizes theme support is defined.

In theme.json v2, the default spacing sizes were only shown when theme sizes were not defined. A theme providing spacing sizes with the same slugs as the defaults would always override the defaults.

Furthermore, there are two settings that can be used to set theme level spacing sizes: spacingSizes and spacingScale. With theme.json v3, presets from both will be merged together and sorted numerically by slug. Presets defined in spacingSizes will override those generated by spacingScale if the slugs match.

In theme.json v2, setting both spacingSizes and spacingScale would only use the values from spacingSizes.

To keep behavior similar to v2 with a v3 theme.json:

  • If you do not have any spacingSizes presets or spacingScale config defined, defaultSpacingSizes can be left out or set to true.
  • If you disabled default spacing sizes by setting spacingScale to { "steps": 0 }, remove the spacingScale config and set defaultSpacingSizes to false.
  • If you defined only one of either spacingScale or spacingSizes for your presets, set defaultSpacingSizes to false.
  • If you defined both spacingScale and spacingSizes, remove the spacingSizes config and set defaultSpacingSizes to false.
--- theme.json v2
+++ theme.json v3
@@ -1,27 +1,25 @@
 {
-	"version": 2,
+	"version": 3,
 	"settings": {
 		"spacing": {
-			"spacingScale": {
-				"steps": 0
-			},
+			"defaultSpacingSizes": false,
 			"spacingSizes": [
 				{
 					"name": "Small",
 					"slug": "40",
 					"size": "1rem"
 				},
 				{
 					"name": "Medium",
 					"slug": "50",
 					"size": "1.5rem"
 				},
 				{
 					"name": "Large",
 					"slug": "60",
 					"size": "2rem"
 				}
 			]
 		}
 	}
 }

Props to @scruffian and @juanmaguitar for assistance with writing and reviewing this post.

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

Social Links block changes in WordPress 6.6

WordPress 6.6 includes some changes affecting both the social link and social links blocks.

HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. changes when using a social links 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. inside a Navigation Block

As of WordPress 6.6, the social links block will be wrapped in a list item (li 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.)) when used in the navigation block. This change fixed an issue where the navigation block produced invalidinvalid A resolution on the bug tracker (and generally common in software development, sometimes also notabug) that indicates the ticket is not a bug, is a support request, or is generally invalid. HTML (the social links block’s ul was nested directly under the navigation block’s ul).

This may affect some themes that depend on the exact nesting of the HTML elements, for example using a selector like .wp-block-navigation__container > .wp-block-social-links.

Here are some examples of how the HTML has changed:

Example of navigation block and social links markup before WordPress 6.6

<ul class="wp-block-navigation__container wp-block-navigation">
  <ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex">
  </ul>
</ul>

Example of navigation block and social links markup after WordPress 6.6

<ul class="wp-block-navigation__container wp-block-navigation">
  <li class="wp-block-navigation-item">
    <ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex">
    </ul>
  </li>
</ul>

Class name changes to the social link block

As of WordPress 6.6, the social link block will no longer output the components-button class name on its button element within the block editor.

Themes targeting this class name for editor styles should use the existing wp-block-social-link-anchor class instead.

It’s expected that most themes will be doing this already, so for most no change will be required.

Why was this class name present?

The class name was a side-effect of using the Button ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. component from the @wordpress/components package (which can also be referenced as wp.components.Button) within the social link block’s implementation.

Why is this being changed?

  • The components from @wordpress/components are intended for use in the editor’s general interface and have a lot of opinionated CSSCSS Cascading Style Sheets., while the on-canvas part of a block is intended to be styled by a theme and should have minimal CSS.
  • Updates made to styles in the @wordpress/components can have unintended side-effects for the block’s appearance, and can also raise or lower the specificity of the styles above or below what a theme implementer might expect. The change to the block’s implementation leads to more stable and predictable css specificity.
  • There’s no guarantee the styles from @wordpress/components will continue to work in the iframed editor canvas, some CSS variable references in the styles were already not working as expected.
  • The styles that were previously added to the social link block contravene the CSS guidelines used by developers on the WordPress project.

Props to @ramonopoly and @juanmaguitar for review

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

Options API: Disabling autoload for large options

Authors: @pbearne and @joemcgill

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

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

[57920] introduces several changes to the Options APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. to optimize autoloading behavior.

Changes to the options API

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

New default $autoload value

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

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

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

Updated database autoload values

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

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

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

Newly introduced public functions and filters

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

New Function

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

New Filters

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

Disabling autoload for large options

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

Preparing for this update

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

Ensuring a large option is still autoloaded

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

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

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

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

Adjusting the threshold for large options

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

add_filter( 'wp_max_autoloaded_option_size', 'my_max_autoload_option_size' );

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

Auditing your site for large options

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

To audit your site for large options that are currently being autoloaded, you can run an enhanced version of this same Site Health check by installing the Performance Lab plugin from the WordPress Performance Team. Once activated, the pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party will add additional information to the Site Health check so you can review and disable any options that do not need to be autoloaded in the Site Health check.

Screenshot of the advanced table shown by the Performance Lab plugin

Other changes to the Options API in WordPress 6.6

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

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

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

Improvements to active block variation detection

WordPress 6.6 includes improvements to how a block variation is detected as active for a given 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. via the variation’s isActive property. This property can be either a function (that compares block and variation attributes), or a string[] shorthand that specifies which of the variation’s attributes to consider when comparing them to the block’s. The following changes affect only the string[] shorthand, which is now generally recommended over the function version.

Dot notation

Block variations can now use dot notation for “object paths” to specify “nested” attributes in their isActive property. For example, if a block’s query attribute is an object, it is now possible to use the following shorthand notation for isActive to determine if a variation is active based on the query object’s postType property:

attributes: {
    query: {
        postType: 'post',
        order: 'desc',
        orderBy: 'date',
    },
},
isActive: [ 'query.postType' ]

This was previously only possible by using an isActive function:

isActive: ( blockAttributes, variationAttributes ) => {
    return blockAttributes.query.postType === variationAttributes.query.postType;
}

Highest specificity wins

If multiple variations have an isActive string array property that matches a given block, getActiveBlockVariation() will now return the one with the highest specificity. For example, take two variations of the same block, one with

attributes: {
    textColor: 'vivid-red',
},
isActive: [ 'textColor' ],

and another with

attributes: {
    textColor: 'vivid-red',
    backgroundColor: 'cyan-bluish-gray'
},
isActive: [ 'textColor', 'backgroundColor' ]

Now if a block instance has attributes textColor: vivid-red and backgroundColor: cyan-bluish-gray, both variations’ isActive criterion will match that block instance. In this case, the specificity of each match will be calculated as the length of each isActive array, and the matching variation with the highest specificity will be returned — in this example, the second one.

Comparison of objects

If an isActive array item is an object, it was previously compared by reference. This has been fixed such that a block is considered to match a variation if it contains all the properties that the variation specifies for that object and if the properties have the same values. For example, the following variation

attributes: {
    query: {
        postType: 'post',
        order: 'desc',
        orderBy: 'date',
    },
},
isActive: [ 'query' ]

matches a block with its query attribute set to

{
    postType: 'post',
    order: 'desc',
    orderBy: 'date',
    offset: 10,
}

But it doesn’t match

    postType: 'post',
    order: 'desc',
    offset: 10,

as the orderBy property that’s specified by the variation is missing.

Comparison of RichText

Finally, rich-text attributes are now compared correctly when used in a block variation’s isActive array. For example:

<pre class="wp-block-syntaxhighlighter-code">attributes: {
    content: 'This is a <strong>warning</strong> message.',
},
isActive: [ 'content' ]</pre>

Conclusion

We hope that these improvements will make developers’ lives easier when working with block variations. They’re also meant to lay the foundations for some other enhancements we’re planning to make to block variations during the next cycle (e.g., automatically added class names for variations, or variation aliases).

Props to @bph and @juanmaguitar for review

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

Grid layout type

The grid layout type for blocks has been in core since 6.3 but 6.6 adds some new features to it:

Toggle between grid modes

Adding grid layout to a block.json without specifying any further attributes, like so:

"layout": {
    "default": {
        "type": "grid"
    }
}

will now by default display a toggle in the blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. 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. layout section, allowing users to toggle between “Auto” and “Manual” modes:

It is still possible to configure the block to default to “Manual” mode and add a specific column count, by using the columnCount attribute:

"layout": {
    "default": {
        "type": "grid",
        "columnCount": 5
    }
}

Set column and row spans on grid children

Blocks that opt into grid layout can also allow their child blocks to span across multiple grid columns and/or rows. This can be enabled with the allowSizingOnChildren attribute:

"layout": {
    "default": {
        "type": "grid"
    }
    "allowSizingOnChildren": true
}

This will enable Column span and Row span controls in the child block sidebar, under the Dimensions section:

It will also enable on-canvas handles that can be dragged to resize the block:

New grid variation for Group block

Group block now has a Grid variation:

Similarly to Row and Stack, Grid comes with allowSizingOnChildren enabled so children of Grid blocks can be resized.

Props to @bph for review and @juanmaguitar for proofreading.

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

Editor: Unified Extensibility APIs in 6.6

WordPress 6.6 unified the different slots and extensibility APIs between the post and site editors. PluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors do not need to integrate their extensions twice (once using wp.editPost and once using wp.editSite). Instead, the following slots are now available under the wp.editor global variable (@wordpress/editor package or wp-editor script handle).

  • PluginDocumentSettingPanel
  • PluginSidebarMoreMenuItem
  • PluginSidebar
  • PluginPostStatusInfo
  • PluginMoreMenuItem
  • PluginBlockSettingsMenuItem
  • PluginDocumentSettingPanel
  • PluginPostPublishPanel
  • PluginPrePublishPanel

Example

// my-file.js
import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel } from '@wordpress/editor';

const PluginDocumentSettingPanelDemo = () => (
  
     Custom Panel Contents
   
);

registerPlugin( 'plugin-document-setting-panel-demo', {
  render: PluginDocumentSettingPanelDemo,
  icon: 'palmtree',
} );

The above script registers a panel in the document 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. for all post types in both the post and site editor. The script can be enqueued in PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher with the right script dependencies:

function example_enqueue_editor_assets() {
  wp_enqueue_script(
    'example-plugin',
    plugins_url( 'my-built-file.js', __FILE__ ),
    array( 'wp-editor', 'wp-plugins' ),
    1
  );
}

add_action( 'enqueue_block_editor_assets', example_enqueue_editor_assets );

Supporting multiple WordPress versions

The wp.editPost and wp.editSite slots will continue to work without changes, but the old slot locations will be deprecated. To avoid triggering console warnings, you can support both the new and old slots at the same time.

To support previous versions in the example above, the Slot import must be updated as shown in the following code:

// my-script.js
const PluginDocumentSettingPanel = wp.editor?.PluginDocumentSettingPanel ?? ( wp.editPost?.PluginDocumentSettingPanel ?? wp.editSite?.PluginDocumentSettingPanel );

Once you are ready to make WP 6.6 the minimum required version for your plugin, you should be able to drop the fallbacks and restore the initial code.

Limiting your extensions per post types

It is important to note that when switching from editPost or editSite slots to editor, your plugin will now load and render in both contexts.

Both editors (post and site editors) have the possibility to render and edit pages, templates, patterns… This means that most plugins probably need to load in both contexts. But you might not want to load your plugin for templates, patterns, or you may only want load your plugin for pages but not posts…

To perform these checks, plugin authors have access to a range of selectors in the coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress./editor data store that allow them to hide or disable their behavior/UIUI User interface as they wish.

  • Some extensions might only make sense to publicly viewable post types (post types that render in the frontend). You can use the postType’s viewable property to check for this.
  • Or you can use the name of the post type to only render for a limited set of post types.

Let’s update the initial example to only render the slot for publicly viewable post types:

// my-file.js
import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel, store as editorStore } from '@wordpress/editor';
import { store as coreStore } from '@wordpress/core-data';


const PluginDocumentSettingPanelDemo = () => {
  const isViewable = useSelect( ( select ) => {
    const postTypeName = select( editorStore ).getCurrentPostType();
    const postTypeObject = select( coreStore ).getPostType( postTypeName );
    return postTypeObject?.viewable;
  }, [] );
  // If the post type is not viewable, do not render my plugin.
  if ( ! isViewable ) {
    return null;
  }


  return (
    
       Custom Panel Contents
     
  );
}


registerPlugin( 'plugin-document-setting-panel-demo', {
  render: PluginDocumentSettingPanelDemo,
  icon: 'palmtree',
} );

Thank you @ndiego @jeherve for contributing to and testing this post and @juanmaguitar for proofreading.

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

Preparation for React 19 Upgrade

WordPress 6.6 will ship with version 18.3 of the React library, which is identical to 18.2 but adds warnings for deprecations and other changes to help developers prepare for 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 once it becomes stable.

It’s recommended to stop using the deprecated features to ensure better compatibility with React 19 when it ships with WordPress. Keeping deprecations unchecked may lead to bugs or unintended behavior in your plugins. Addressing them is important to ensure smooth and reliable functionality.

Removed: defaultProps for function components

When searching the pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and theme repo for the use of deprecations in React 19, this one was found to be common.

React 19 will remove defaultProps for function components in favor of ES6 default parameters. This change can cause unexpected side effects when a component relies on default values provided by defaultProps.

// Before.
function Welcome( { text } ) {
	return 

{ text }

; } Welcome.defaultProps = { text: 'Howdy!', }; // After. function Welcome( { text = 'Howdy!' } ) { return

{ text }

; }

Please refer to the official React 19 upgrade guide for a full list of deprecations and changes.


Props to @kirasong for review and @juanmaguitar for proofreading.

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

JSX in WordPress 6.6

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

How to use the new JSX in WordPress 6.6

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

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

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

Build Tools Compatibility and upgrade path

If you’re using the JSX syntax in your code base, and as long as you don’t update your dev dependencies (including @wordpress/scripts, @wordpress/babel-preset-default or @wordpress/dependency-extraction-webpack-plugin), you will continue to use the old JSX transform. This will allow your pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and built files to be compatible with WordPress 6.5, earlier versions and WordPress 6.6 as well.

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

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

Going forward

The new JSX transform comes with performance improvements and optimization. 

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


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

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