How to Create a Multifaceted WordPress Site Without Using a Multisite

Or, How to Create a Multisite Without Using a Multisite Installation

A WordPress Multisite installation is a great tool, but it comes with great weaknesses. Read to discover a more efficient solution.

The problem: the need for multiple site facets, and the weaknesses of a Multisite

Some projects require multiple versions of a main, or a prototype, site. WordPress has a built-in solution for such cases – Multisite. A Multisite WordPress installation has one source-code and many databases – one for each site. This can be perfect for some cases, but it has several disadvantages in others:

  • Dealing with multiple databases is resource-hungry.
  • You can’t share database tables between your subsites. For example, you can’t use the same WooCommerce product catalog everywhere.
  • Not all plugins support Multisite.
  • Some plugins might require a premium subscription for Multisite support.
  • Some premium plugins require a license per Multisite subsite.
  • Multisite support is, in a way, an interpretation of the plugin creators – “What does Multisite mean in our plugin’s case?”. Some plugins might implement Multisite support in a way that makes no sense for your project.
  • Duplicating a Multisite subsite is a problematic process.

Luckily, for many cases, there is a much better solution. You can build a multifaceted WordPress site with one code base and one database…

The challenge: not breaking or changing character

Basically, we want to present the same site, with some modifications according to the subdomain it is accessed by. It will be the same site, but it will act a bit differently, following predefined settings. The first step will be to direct a subdomain to our site. It will work for the homepage, but most links on the homepage will take the user back to the primary domain. Our site will break character. This is because most links on a WordPress site are built using the home or siteurl options value as the link’s base URL. Usually, these are database values. And, because the database is unaware of the subdomain used to access the site, it will continue to supply the primary domain as the base URL for links. One way to try is to change these database options live. But this isn’t a good path. It adds unnecessary database calls. But, more crucially, the database can only hold one value at a time – if multiple users are visiting the site, their sessions will probably get mixed at some point. Our site might change character unexpectedly during a visitor session. Luckily, there is a way to bypass the database.

The solution : WP_HOME and WP_SITEURL to the rescue

The WP_HOME and WP_SITEURL constants allow bypassing the home and siteurl database values. Using these constants, we can hard-code the values into the site itself. The database won’t be queried for them anymore. The hard-coded values will only apply in the context of the currently-running script, and so won’t affect other users. Now, our site wouldn’t break or change character. Perfect.

Using ACF, it’s an easy pathed road from here. I will use the case of a multi-facets WooCommerce store for a detailed implementation guide.

This is how to build a multi-facets WooCommerce store without a Multisite:
(a complete code example follows below)

  1. On wp-config.php, get the base URL of the current visit

    $base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]";

  2. Define it as the home and siteurl values

    define('WP_HOME', $base_url);
    define('WP_SITEURL', $base_url);

  3. Register Stores post type

    Using core register_post_type() function.

  4. Create custom fields for the Stores post type

    For example, Logo and Primary Color. Using ACF or an alternative.

  5. Create stores posts

    NOTE: The store slug must match the required subdomain.

  6. On functions.php, get the visited subdomain

    See the complete code example below.

  7. Check if the visited subdomain has a matching store post

    – Using core get_page_by_path() function.
    – If it doesn’t – redirect somewhere.
    – See the complete code example below.

  8. If it does, get the respective store settings object (the custom fields values)

    – Cache it for performance.
    – See the complete code example below.

  9. Do stuff according to the store’s settings

    You can do basically anything. From changing the logo and primary color to changing a specific product price.

That’s it. You have a multi-facets WooCommerce store.

All together now (step numbers are marked using square brackets):

<?php ###> wp-config.php <### ## [1] Get the base URL of the current visit ## $base_uel = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]"; $base_uel = htmlspecialchars($store_url); ## [2] Hard-code the base URL as home and siteurl values ## define('WP_HOME', $base_uel); define('WP_SITEURL', $base_uel); ###> functions.php <### // A function to get the current visited store object function get_current_store_object() { // If already set by a previous function call during the page-load, return the current store object ([8]) static $current_store_object; if (isset($current_store_object)) { return $current_store_object; } ## [6] Get the visited subdomain ## $host_parts = explode('.', $_SERVER['HTTP_HOST']); $host_parts = array_map('htmlspecialchars', $store_host_parts); if (false !== ($key = array_search('www', $host_parts))) { unset($host_parts[$key]); } $current_subdomain = $host_parts[0]; // Check if the user is visiting the primary domain. $host_parts_reversed = array_reverse($host_parts); $primary_domain = $host_parts_reversed[1]; if ($current_subdomain === $primary_domain) { // The user is visiting the primary domain. } ## [7] Check if the visited subdomain has a matching store post ## if ($current_store_page = get_page_by_path($current_subdomain, ARRAY_A, 'store')) { ## [8] If it does, get the respective store settings object (ACF assumed) ## // As $current_store_object is defined as static, its value will be saved for sequential function calls during the page-load $current_store_object = get_fields($current_store_page['ID']); return $current_store_object; } else { // No store matching the subdomain. Redirect somewhere } }
Code language: HTML, XML (xml)

Conclusion

A WordPress Multisite installation is a great tool. But, as it consists of multiple databases – one for each subsite – it comes with many weaknesses. As an alternative, the WP_HOME and WP_SITEURL constants allow you to build a multifaceted site with one source code and one database. Kind of a Multisite without a Multisite.

Leave a comment

Your email address will not be published. Required fields are marked *