Routing URL Requests to Sites in WordPress Core

I’ve been thinking a lot over the last many months on how to approach the use of varying URL structures in a single multisite installation of WordPress. Another conversation on Twitter tonight reminded me there are quite a few developers out there itching to improve the process. I’m going to attempt to convey my current thoughts here.

In the comments of a great write up on a potential roadmap for the future of multisite in WordPress core, Andrew Nacin has this thought:

Your comment made me realize I need to stop calling it “domain mapping.” This wording stems from the fact that a top-level domain is “mapped” to an existing subdomain or existing subdirectory.

Multisite has historically been a choice between two options: Am I going to organize all of my sites with subdirectories or subdomains?

  • `http://example.com/sitename1/`
  • `http://sitename1.example.com/sitename1/`

This is great if the structure of sites you’ll be maintaining on your network is planned this way. The wrench usually appears when an entirely new domain needs to be supported.

  • `http://newexample.com/`

It’s at this point when a developer can turn to a plugin solution–likely WPMU Domain Mapping–to map this domain to an existing site in a subdirectory or subdomain structure.

  • When a request for `http://newexample.com` is received, load `http://example.com/newexample/` OR
  • When a request for `http://newexample.com` is received, load `http://newexample.example.com/`

Of course a more complex requirement may come up at some point that involves something more than just a new domain.

  • `http://newexample.com/subsite1/`
  • `http://sitename1.example.com/subsite2/`

The solution required here is some sort of custom `sunrise.php` file to help route requests combined with some process to store domain and path information for each site into the `wp_blogs` table in the database. I’ll offer the sunrise we’ve started to use at WSU as an example.

This is where the true mapping happens, whether it’s done by WordPress core in `ms-settings.php`, a sunrise file provided by a developer, or by the sunrise file provided by the WPMU Domain mapping plugin. A requested URL is parsed into a domain (host) and a path (subdirectory). This information is then checked against something, likely `wp_blogs`, to determine what `$blog_id` and `$site_id` should be used when loading WordPress.

So continues our unfortunate nomenclature. `$blog_id` is telling WordPress what site to load. That site happens to belong to a network which is tied to `$site_id`.

Anyhow. This is how we should think of the entire process:

  • When a request for this domain and path is received, use this site’s information when loading WordPress.

Beyond a few sanity driven technical limitations, such as nested subdirectories, we shouldn’t care too much about that domain and path combination. Our primary concern when a request is received is whether or not that domain and path match an existing site in the database. If they do, then we can properly load all of the data associated with that site and it’s parent network.

There are a few additional caveats that will be related as we figure this out:

  1. Cookie management. If a user is a member of a single site, this should be no trouble. If a user is a member of sites that have different domains, then this becomes a harder issue to account for. One option is to require that user to login twice to access both sites. If we’re good, we can take care of both at once.
  2. Conflicts. When supporting a mix of domains and subdirectories, we’ll want to make sure that those subdirectories don’t conflict with other possible slugs created with content or by WordPress core. If `http://example.com/` has a page slug of `howdy`, we don’t want to allow the site `http://example.com/howdy/` to be created.
  3. Allowed characters. A mixture of rules exists in WordPress core at the moment around user and site creation. We’ll want to confirm what characters we want to allow in domains and in paths when sites are created.

I’m not sure if this all helps us figure out what to call it, but I do think something like routing is more apropos than mapping. This is part of a routing process that takes pieces of a requested URL and determines what to output as a response.

Leave a Reply