meta api

Adding the Networks endpoint to WordPress core

So as part of the Nijmegen WordCamp, I run the core team at the contributor day. Even through this took up a lot of my time, I still had a little time to work on networks endpoint for core. There was an existing ticket for this and it is on the Multisite roadmap that we have been working on. But of the two require endpoints for full support of the multisite is core (sites and networks), networks may seem like the less important of the two. After all, networks are created rarely (in most cases only once) compared to sites, where sites can be created all the time. However, there is one important feature of multisite that doesn’t have api rest endpoint that really needs it and that is network options. Adding a networks endpoint would add an api not only for networks but also it’s options (meta) as well.

Network options, a history

Network options (or site options as they are sometimes known) different from site level options and are not a feature of WordPress that many people know about it. Network level options are used to core network level configuration in multisite, however not many plugins bother with network level settings. This is partly because many developers do not bother to test their plugins with multisite. The other reason is there isn’t currently a developer api to add network pages and settings easily. For single site WordPress, there is a settings api that makes it easy for developers to build out there own settings panels in the admin terminal. However, there is nothing like this for multisite. Currently the process adding a network options is manual, adding to manual posts requests and manually saving values in the database. This means that developers have to do all their own data sanitation and escaping themselves. There is a ticket to add a similar network settings api written by one Joost de Valk the creator of WordPress SEO however this ticket at time of writing is over 7 years old. With a new endpoint for networks in core, we have an opportunity to improve the whole network options interface. Once there is api for networks, developers can use the CRUD (create, read, update and delete) methods to interact with options and not need to have to do all the data sanitation themselves. We can can extend this more, by creating a network settings interface, that allows developers to register settings to network settings pages. There network settings pages, then become a single page application written in React or similar. This could result in some really nice user interface and make network settings a better than site level settings.

Blocker to this bright future

Even through there is now a patch up for a networks endpoint, there is a lot of work to be done. Currently the first patch, only has read methods. This is because in core there are not currently create, edit and delete network functions. To add this functionality to the api, the functions must be added to core. There is a ticket for this that are based on some of the code in WP Multi Network plugin. The reason these functions have no been added before, is because it would then mean that WordPress core officially support multi network setups. Core has unofficially support multi network for a while, with many commits (#40486, #40590, #40591) going in the last couple of releases. Adding these functions to add a maintenance cost as well, the multisite codebase is large and only has a couple of maintainers work on it at any given time.

Another blocker are the current CRUD functions for network options. Currently there are following functions

  • get_network_option
  • add_network_option
  • update_network_option
  • delete_network_option

I worked on these functions  as part of the 4.2 release and were introduced in #34777 . However, these functions were just a simple replacement for the existing *_site_options functions. I wanted to go further  with these functions and use it as a chance to leverage the meta api. Under the hood, network options are stored in a sitemeta table. This means that data is structured like meta in the database. This means that the meta api used by post / user / comment / term meta could be used here. It adds a number of key benefits, including

  • Improved caching profile
  • New filters and actions
  • Enables use of register_meta
  • All improves to meta api, filter down to network options.
  • Possible integration with fields api

I have been working on a ticket for a while now, however this is not a small change. It fundamentally change network options and that has effect on every piece of code that uses them. An example of the effect is if code is saving network options for id 0. It is impossible to have a network with id 0, however some plugins have been using 0 as a way to store global settings. This would break if we use the meta api doesn’t allow for 0 or negative numbers.

As you can see, there is a lot of work to done to make this a networks endpoint happen, but I think it is really worthwhile. Once this work is done, it will make developing for multisite much easier.

How you can help

The key tickets that need feedback and code review are

Any help with these tickets is more than welcome. You can also join in on a weekly multisite meetings on slack in the #core-multisite channel every Tuesday at 4pm UTC.

 

Introducing site meta

There is a new feature that is coming to WordPress multisite is and it is called site meta. This new functionality, was originally purposed by John James Jacoby and it is key building block for the future of multisite. But to understand it’s importance, you must first understand how WordPress multisite is built.

The basics

There are two key concepts that you have to understand about multisite before continuing, sites and networks. Basically, once you install multisite, it installs some new tables in the database.  These tables are used to store data from the networks and sites. The default installs of multisite installs one network and a single sites. All sites are part of a network, but it is also possible to have a multi network. See JJJ’s amazing wp-multi-network for more detail. Currently if you want to extending multisite, it is easy to extend networks, as there is already a network settings, which stores networks meta table. Developers can already create their own network options pages and store data as a network. Plugins like yoast and jetpack already do this. But if you want to extend a site, it not currently possible. Developers can store site level data in the options table for each site. This is fine, however, within the multisite context it is hard to query this data out the database because how the data is stored. Take for example, if you wanted to query sites by site name this is impossible. The only way search by name, to get all sites and loop around each one, switch to site and compare the result in php. Something like this.


$site_name = 'spacedmonkey';
$site_ids = get_sites(['fields' => 'ids', 'number' => -1]);
foreach($site_ids as $site_id){
    switch_to_blog($site_id);
    $option = get_option('sitename');
    if($option == $site_name){
      // Found it!
    }
    restore_current_blog();
}

There are plugins that extend currently extend multisite. The most popular of which is WordPress MU domain mapping which installs a new table ‘wp_domain_mapping’ in the database. Installing new tables into database isn’t a bad thing, but it can be problematic. Firstly, the installation of said table isn’t guaranteed to work. There can be issues database permissions or a table of that name already exists. Also any non standard table, all caching will have to handled manually in code by the developer.

The site meta adds a new table into core database, that enables developers store per site data in a uniform way. There will be a full API to interact with this data in databases. The new functions include.

  • add_site_meta
  • delete_site_meta
  • edit_site_meta
  • get_site_meta
  • delete_site_meta_by_key
  • update_sitemeta_cache

This will make it easy for developers to extend multisite and make many things possible. The new table will on all new multisite installs and the new table will be added when you run the database upgrade in the network admin screen. The is a new helper function called is_site_meta_supported what automatically detects if the table exists.

This new feature is currently in development, your input is value, please leave your comments in trac.