Multisite registration and activation pages have new HTML and CSS

In WordPress 6.1, the forms for the wp-signup.php and wp-activate.php pages have several enhancements to both the markup and the styles.

AccessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility)-related improvements

Indicating relationships:

  • Fieldsets, with visible legend text, group the radio buttons.
  • Form field description information connects to its related field with aria-describedby.
  • When present, error messages also connect to their field with aria-describedby. The generic error has an ID in case custom fields should refer to that.

Preventing errors:

  • Required text fields have the required attribute.
  • The Site Name label indicates that users should enter the subdirectory only, and the Site Domain is only the desired subdomain.
  • The Username field’s description text now specifies that letters need to be lowercase.

Color contrast:

  • If the activation page has an error message, its default dark gray text color contrasts against the light background.
  • The default style for links within the registration page’s bordered message (.mu_alert) includes an underline and matches the text color of the rest of the message. For example, Twenty Twenty-One’s dark mode assigns a light link color, so the new style makes it readable and identifiable as a link. If a theme uses a bottom border or box-shadow on links, however, this underline could be inappropriate.
“Options page” link had light gray text in Twenty Twenty-One’s dark mode
Links were sometimes difficult to see
“Options page” link is in the same dark gray text as the rest of the message
Links match the surrounding text color, underlined, in 6.1

New elements and styles for the registration page form

  • The fieldset and legend elements reset margin, padding and border properties.
  • The legend styles are consistent with the default label font size, weight and margins.
  • Radio buttons are inside paragraphs without a top margin, following the legend.
  • Text input fields and the submit button, which were set to 100% width plus padding, are only as wide as their container now.
screenshot of account setup page in WordPress 6.1
New account setup, step 1, allowing both sites and usernames

When people create an account:

  • Descriptive text for the Username and Email Address is inside paragraph tags. Because these immediately follow the input, the paragraphs do not have a top margin.
  • Options for creating a site and/or a username are grouped in a fieldset with a new, visible legend.
  • Elements with the “wp-signup-radio-button” class wrap these options’ radio buttons and their labels, and with “display: block” the options stack vertically.
screenshot of form with Site Name (for subdirectory installations), Site Title, Site Language and Privacy options
Form fields for an administrator (logged in) to create a new site

When an administrator creates a new site:

  • A “wp-signup-blogname” container wraps the Site Name (or Site Domain) input with the domain, so themes could arrange them side-by-side.
  • For right-to-left languages, the domain and its input field remain in the left-to-right direction.
  • The “privacy-introfieldset uses paragraph tags inside it to retain most paragraph styles from the theme.
  • By wrapping “Privacy:” in a “label-headingspan, it appears above the rest of the legend. This text maintains the same default font size and weight given to the legend and label elements.
  • The “Yes” and “No” labels have moved next to the radio buttons, instead of inside them. Without the strong emphasis tags, these can match the default label font weight of 600. If any theme overrides the “.mu_register label.checkbox” selector to block display, that property will need updating to an inline style.
  • In this fieldset, “wp-signup-radio-button” containers remain next to each other, with a small margin between them.

Site activation page styles

screenshot of site activation page with Twenty Twenty theme
  • The activation form’s container is centered, to match the signup page.
  • The input field and submit button cover the full width of the container, with box-sizing: border-box to prevent them from extending beyond 100%.
  • The form and .error selectors now include .wp-activate-container so that the styles do not affect elements in the headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. or footer.

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

This is not new to 6.1, but block themes should continue to include header.php and footer.php template files for these pages. To make a header template more specific to the networknetwork (versus site, blog) pages, its filename can be header-wp-signup.php or header-wp-activate.php.


For more information about the HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. and CSSCSS Cascading Style Sheets. changes, view tickets #40361 and #54344.

Props: Thank you, @ironprogrammer, @webcommsat, @audrasjb and @joedolson, for peer review and editing.

#accessibility, #core-multisite, #dev-notes, #dev-notes-6-1, #multisite, #themes

Multisite improvements in WordPress 6.1

NOTE: Due to issues reported in #56845, this enhancementenhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. was reverted in r54637 and will not be included in the final 6.1 release. Work will continue in 6.2 and beyond. Please follow along in the original TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. Ticketticket Created for both bug reports and feature development on the bug tracker. (#37181)

Using the metadata 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. for networknetwork (versus site, blog) options

The way that network options are accessed is changing in WordPress 6.1. Network options have always been stored in a meta table called sitemeta. This name is confusing, as “site” in this context means “network,” not to be confused with blogblog (versus network, site) meta, used to store site metadata. Prior to WordPress 6.1, the functions get_network_option, add_network_option, update_network_options, and delete_network_option used custom database queries and caching. This resulted in some performance issues and lots of code to maintain.

In WordPress 6.1, the network options functions have been updated to use the more established metadata API, which is already used for metadata of other object types like posts, terms, and users. This effectively makes a function like get_network_option a wrapper around get_metadata. This has a number of advantages including:

  • Consistency with other metadata types
  • Support for register_meta functionality, such as default values
  • Improved cache priming 
  • Fewer database queries, as all network options are primed in a single request 

Along with these improvements, WP_Network_Query has a new parameter called update_network_meta_cache that allows for all networks in the query to prime the network options in a single query. 

One side effect of this change is that newly updated network options using an integer value may result in a string being returned. When using values like this with an integer comparison, it is important to allow cast to an int. In the old implementation, the second page load of the option would have resulted in returning a string. This change can be considered a fix but it is different from the current behavior. 

This change makes cache group site-options no longer in use and a candidate to be removed in future releases. 

For more information, visit Trac ticket #37181

Store main site ID of network in network options

When a multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site is created in WordPress 6.1, the main site ID on the network is stored in network options. As the main site on the network does not change in most cases, this is a value that can be stored for future reference. This saves a call to WP_Site_Query to look up the main site by domain and path in the bootstrap process which makes This lookup wasteful and not needed. This change also helps setup multiple networks, as noted above, since network options are primed in a single request. This means that when looking up multiple networks, the main site ID is now primed in along with other network options, resulting in fewer database queries / cache lookups. 

For more information, visit Trac ticket #55802

Thanks to @flixos90 and @milana_cap for peer review, and @mxbclang and @webcommsat for proofreading.

#6-1, #core-multisite, #dev-notes, #dev-notes-6-1, #multisite, #performance

Multisite Roadmap Published

Over the past year, the multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site team has been looking at possible features to add or improve support for, what some of the pain points are and last but not least how to align with the coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. focuses for this year, which for multisite scope basically means working on REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. support and usage.

The result of those long discussions is a clearly defined roadmap, describing what the priorities will be over the next couple months or generally the near future. It should be clarified that this is a living document that will see updates from time to time as tasks get completed or new decisions are made.

The roadmap document lives on a separate page to be easily accessible outside of the blogblog (versus network, site), and also to allow other component teams to possibly follow with their own roadmaps.

Here is what the roadmap focuses on at this point of publication:

  • REST API support for users, sites and networks
  • new internal APIs for sites and networks
  • introduction of site metadata
  • internal usage of the MetaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. 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. for networknetwork (versus site, blog) options
  • file organization improvements

All the above will set a solid foundation to after their completion finally focus on some long-needed more user-centric enhancements, particularly to the administration panels. Other long-term changes include improving test coverage and global context support. Those areas are also described a little more broadly in separate sections towards the end of the roadmap.

Please refer to the roadmap document for a full and current overview of multisite priorities.

#core-multisite

Approaches for a complete sites endpoint and an expanded WP_Site_Query

Multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site office hours are held every Tuesday at 16:00 UTC in #core-multisite. The next will be Tuesday 16:00 UTC.

Creating a useful sites/ endpoint for the REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. and making WP_Site_Query more useful have been frequent topics over the last few weeks in #core-multisite. Quite a bit of discussion has been centered around the idea of a global wp_blogmeta table, whether it’s a good fit for coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., and (if so) how to approach its introduction. See #37923 and the previous make/core post discussing a sites endpoint for additional background.

The intent of this post is to step back a bit and clarify the issues at hand to help identify the right solution(s).

The initial site information problem

A request to a global wp-json/wp/v2/sites/ endpoint on a networknetwork (versus site, blog) should return a set of site objects, similar to how wp-json/wp/v2/posts/ returns a set of post objects. A request to wp-json/wp/v2/sites/4 would return a single site object.

Written today each site object, represented as WP_Site in PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher, would provide at least this data:

  • ID
  • domain
  • path
  • registered
  • last_updated
  • public
  • archived
  • mature
  • spam
  • deleted
  • lang_id

The above fields all mirror what is available in the global wp_blogs database table installed with multisite. These are useful on their own, but additional data is frequently required.

Example: One piece of the adminadmin (and super admin) that would be great to power with the REST API is the My Sites menu that multisite users see in the toolbar. To build this view, the home URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org, admin URL, and site name are all necessary. In PHP, this data is made available through magic properties on the WP_Site object. When home, siteurl, blogname, or post_count is requested, the site uses switch_to_blog() and get_option() to populate the data from the individual site’s options table. If 25 sites are on the list, this generates 25 context switches and accesses 25 different tables.

There are at least a few approaches here:

  • Mirror the existing PHP experience and ensure properties are populated before the REST API response is returned. Possibly introduce a lighter weight switch_to_blog() option.
  • Provide a basic site object as well as an option to _embed other data in the response.
  • Migrate these properties into wp_blogs from wp_#_options as additional columns.
  • Migrate these properties into a global wp_blogmeta table.
  • Migrate these properties into another shared global space.

The querying sites problem

It’s currently possible to query for sites by the default fields listed above. This data is useful for querying, but it would also be nice to query by a site’s name, description, or other piece of data at a global level.

Example: In the list table that displays all the sites of a network, it’s possible to query by a site’s domain or path, but not by it’s actual name. In a large network, a user may find it difficult to find a site when many sites share similar domains or paths. The user may know the site’s title, but not the address itself.

There is no real workaround for this issue in core right now as each site’s name is stored individually in that site’s wp_#_options table and cannot be queried collectively.

Possible approaches:

  • Migrate these properties into wp_blogs() from wp_#_options as additional fields.
  • Migrate these properties into a global wp_blogmeta table.
  • Migrate these properties into another shared global space.

Feedback please

Please leave any thoughts you have on possible approaches to these 2 problems. It would be especially helpful to identify some use cases that may not yet be clear, or approaches that are not listed above. All feedback is welcome. 🙂

#multisite, #rest-api

Providing a REST API sites endpoint for multisite

One of the objectives for multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site is to determine how sites can be managed with the REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/.. This has been an agenda item for the last two weeks and quite a bit has been processed. This will continue to be a topic, so please stop in for #core-multisite office hours on Tuesday 17:00 UTC and please leave your feedback in the comments on this post.

January 17 chat log and January 24 chat log in #core-multisite

Attendees: @kenshino, @vizkr, @danhgilmore, @iamfriendly, @flixos90, @schlessera, @sergeybiryukov, @pbearne, @paaljoachim, @streetlamp, @jnylen0, @loreleiaurora, @maximeculea

The requirements for the /sites/ endpoint can be summed up with these assertions:

  • The /sites/ endpoint should provide a useful set of data for each site without requiring the use of switch_to_blog().
  • It should be possible to query /sites/ for something other than ID, domain, and path.

In its current state, any /sites/ endpoint is limited to the fields in the wp_blogs table. Data such as a site’s name and description are stored in each individual site’s wp_#_options table.

Given a list of 20 sites, switch_to_blog() will be used 20 times so that get_option() can be used to retrieve things like home, siteurl, blogname, and blogdescription. An example of how inefficient this is can be found in the generation of the My Sites menu. Caching has gotten better with the introduction of WP_Site and WP_Site_Query, but there is an opportunity to change how the information is stored.

In #37923, @johnjamesjacoby suggests the introduction of a wp_blogmeta table that provides access to some site information in a common table. After discussing this in the January 17 chat, @iamfriendly and @flixos90 agreed to each take a look at coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.’s default options stored in wp_options and determine which made sense in a shared wp_blogmeta table. Richard’s results can be found in a comment on the ticket and Felix’s in the Slack discussion.

After some discussion in the January 24 chat, that list can be pared down a bit more.

  • home
  • siteurl
  • blogname
  • blogdescription
  • admin_email

The creation of a new table, wp_blogmeta, and migrationMigration Moving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies. of data for each site from wp_#_options is something that needs feedback. Without this change, a /sites/ endpoint is still possible, but may be limited. With the change, a /sites/ endpoint is much more useful, but requires a careful migration process.

#multisite, #networks-sites, #rest-api