A terminology nightmare: blogs, sites, networks, and the super admin

The goal of this post is to confuse you, and your head will probably hurt by the end. This is a process story on how we came to decide terminology for WordPress 3.0, and why many functions are so detached from the terminology used in the UI.

The main feature of the WordPress 3.0 is the merge of WordPress MU. MU, or multi-user, was a fork of the codebase designed for many blogs and many users, all on one install.

Your WordPress 2.9 install is a blog. WordPress MU hosts multiple blogs in a site, with the site’s subdomains or subdirectories each being a blog. Technically, MU can support multiple sites, whereas each site is a domain, and each site will have more than one blog.

Thus, example.org is a site (and also the main blog for the site), blog.example.org is a blog on the example.org site, and blog.example.com is a blog on the example.com site. All of this can be managed by a single MU installation. The cross-domain aspects require a plugin, but subdirectories or subdomains are out of the box.

Here’s where it got fun. Come WordPress 3.0, there was a UX decision made to call a blog a site, and remove the “blog” terminology.

You can see where this is going.

If a blog is now a site, then what does a site become? “Domain” is one option, but we didn’t want the connotations that came with that. (More on that later.)

When the merge began, the core developers began to use multisite internally to mean many blogs (well, sites), shortened to “ms” where possible, thus removing the “mu” and “wpmu” prefixes on files and functions.

Surely, we can make this more difficult. And so, just as the UX decision was made to call a blog a site, we decided to call a multisite a network.

The function get_option(), as you know, fetches the specified option for the blog (a site, in the new UI parlance). But MU has two other variations of the options API. One is get_blog_option(), which is used to get the specified option for another blog. So we could leave get_option() as is, and rename get_blog_option() to get_site_option().

Right? Nope.

See, the other API that MU has is get_site_option(), which are options for the entire MU site (in 3.0 parlance, that’d be multisite or a network). So get_blog_option() would be for sites (formerly known as a blog), and get_site_option() would be for multisites (or networks). (We also don’t generally rename the underlying functions only when the UI changes for UX reasons.)

A lot of discussion centered around the options API. There are no options across an entire MU multi-domain install, but we still thought about that and it caused plenty of confusion. We also considered get_sitewide_option(), get_domain_option(), get_multisite_option(), and yes, even get_thingieswide_option(). In despair, one suggestion was thing, thingy, and thingies, to replace blog, site, and network. (Edit: I’ve checked the logs, and it was core dev Peter Westwood who proposed this gem.)

Still with me?

We have this other MU function, called is_site_admin(). An MU site admin has complete control over the site’s settings and all blogs. (In 3.0 terms, these users have complete control over the network’s settings and all sites.)

In order to complete the merge, we’d need to make a lot of is_site_admin() calls all over the place. This function should return true if it’s a network admin, but also true if the user is an administrator on a single-blog (single-site?) installation. (MU blog admins have lesser privileges than both MU site admins and single-install admins.)

The problem is, many plugins check for the existence of is_site_admin() to determine whether it’s MU or a single-install, which means we could only use it in files that are only loaded when we’re running multisite. So much for that.

Thus, is_site_admin() was the first MU function to be deprecated. We started a new deprecated file to be included only when running multisite (and we ended up adding 3 more deprecated files for other contexts). Thus, old plugins using function_exists('is_site_admin') will still work. (For reference, you should now use is_multisite() — do not rely on any constants such as MULTISITE.)

Now what? Well, we needed a replacement for is_site_admin(). Since we aren’t changing any terminology in the code, remember, its current name would have been preferred.

Early candidates, is_multisite_admin() and is_network_admin(), pose terminology problems of their own. An MU site admin isn’t necessarily a site admin for another domain on the same install, and there were some concerns that these functions could falsely connotate multiple domains.

This brings up another problem we have yet to address: If a network (an MU site) has many blogs (err, sites), then what is a collection of many MU sites across domains? (We defined “network” as not spanning domains.)

Ultimately, we decided on is_super_admin(), as that is what many will end up referring to it as anyway. This later inspired talk of capes, but I digress.

“Leave API as is and let UI do what it wants,” Ryan Boren said. “Expect devs to be able to bridge the terms.” To do that, I wish you all lots of luck.

This is more or less a summary of an actual IRC conversation among a handful of contributors and developers, including myself. It was mind-numbingly confusing. I would link to the logs, but its contents make a lot of smart people look really silly. Okay, fine, the logs are here — but I’m only sharing it with you because now that I’ve located them, I realize this post has only scraped the surface of the confusion, and you deserve a bigger headache. For reference, Ryan’s quote above came from the IRC discussion.