This will show you how to use a single installation of WordPress for multiple sites.

This is not to be confused with WordPress’s multisite and is an excellent way to handle a single WordPress location to run multiple domains off of.

I have been using this for local development for over 7 years and I have multiple corporate WordPress websites running off this same setup.

The benefits:

  • Code separation
  • Central control of WordPress versions
  • Quick site setup
  • Simplifies development
  • Easily revert back to older version of WordPress if upgrade fails
  • Complete control over the update process (could be a con but I disagree)

The cons:

  • None yet… over 7 years and I never have yet to have an issue with this setup
    • Asides from a very few poorly written themes and plugins but that could be a benefit as far as I am concerned

 

For this to work as expected, there are a few things that need to be understood.

  • This requires symbolic links to work
    • I have even used this in Windows without an issue. To make symlinks easier in Windows, you could install the Link Shell Extension.
  • WordPress will be installed in a sub-directory as far as WordPress setup is concerned
    • You will still have your own wp-content outside of the subdirectory but I will discuss that towards the end.
    • I will discuss this more because the official page on this over complicates the process.
  • This requires a global wp-config.php that I will provide.
    • Each site has constants that need to be added to their own wp-config.php to ensure site separation of content.
  • This requires that you have all sites installed in a single directory (e.g. home) and each site’s directory is the ServerName in the virtualhost.
    • Basically, you will name your site directories the same as your domain (e.g. www.domain.com)

 

Setup Global WordPress Versions

With the basics covered, this is the process to setup a global WordPress installation:

  • Create a directory named wordpressVersions in the same directory you install the sites.
    • This is where all WordPress version will be installed.
  • Download any version of WordPress that you want to install
    • Extract the WordPress version into wordpressVersions and name the directory to the version of WordPress you downloaded
      • This keeps your versions easily identifiable
      • The point here is to have subfolders inside wordpressVersions for each version of WordPress needed
  • In the wordpressVersions directory, create a new PHP file: wp-config.php
    • This is not the same as your site config, use this code for the file:

wp-config.php

<?php
/**
 * Global WordPress config to allow for a single install of WordPress to be used on multiple sites using symlinks
 * This config is required due to the way WordPress loads the config file.
 * WordPress will check outside the WordPress directory to load a config.
 * Due to symlinking, this means that it checks outside the version directory (which is the global WordPress directory, not the site directory)
 * This config ensures it loads the correct config as well as setting some global constants that can be used in site configs
 * The defaults in this config works for most installs.
 *      (The web root directory, putting WordPress in it's own directory. ie: public_html/wordpress)
 * If you have WordPress in sub-folders of web root, you will need to override a constant to point to the correct directory.
 *      (ie: public_html/some_sub_dir/wordpress)
 * The only constant that needs to be set for sub-folder installs is: GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION
 *      (This needs to be set in the index.php file of the sub-folder install, as this is what loads the proper wp-config file)
 */
 
 
/**
 * GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION
 * The location from the web root, no leading or trailing slash.
 * Use forward slashed only (/) if multiple sub-directories
 * NOTE: This must be used in the index.php file of the location of the sub-directory install
 */
if (!defined('GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION')) {
    define('GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION', '');
}
 
/**
 * GLOBAL_WP_DEFAULT_WP_CONTENT_DIR
 * This is the server path to the wp-content directory
 * Override this value if using WordPress in sub-folders of web root
 */
if (!defined('GLOBAL_WP_DEFAULT_WP_CONTENT_DIR')) {
    define('GLOBAL_WP_DEFAULT_WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'] . (GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION ? '/'.GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION : '') . '/wp-content');
}
 
/**
 * GLOBAL_WP_DEFAULT_WP_CONTENT_URL
 * This is the URL to the wp-content directory
 * Override this value if using WordPress in sub-folders of web root
 */
if (!defined('GLOBAL_WP_DEFAULT_WP_CONTENT_URL')) {
    define('GLOBAL_WP_DEFAULT_WP_CONTENT_URL', 'https://' . $_SERVER['SERVER_NAME'] . (GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION ? '/'.GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION : '') . '/wp-content');
}
 
/**
 * GLOBAL_WP_DEFAULT_DISALLOW_FILE_EDIT
 * This is the global to disable file edits on the site.
 * This is used if added to the site's config file
 */
if (!defined('GLOBAL_WP_DEFAULT_DISALLOW_FILE_EDIT')) {
    define('GLOBAL_WP_DEFAULT_DISALLOW_FILE_EDIT', true);
}
 
/**
 * Disable auto update
 */
if (!defined('WP_AUTO_UPDATE_CORE')) {
    define( 'WP_AUTO_UPDATE_CORE', false );
}
 
/**
 * Disable auto updater
 */
if (!defined('AUTOMATIC_UPDATER_DISABLED')) {
    define( 'AUTOMATIC_UPDATER_DISABLED', true );
}
 
 
// load site-specific configurations
require_once $_SERVER['DOCUMENT_ROOT'] . (GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION ? '/'.GLOBAL_WP_DEFAULT_WP_SUBDIR_LOCATION : '') . '/wp-config.php';

It should be noted that GLOBAL_WP_DEFAULT_WP_CONTENT_URL is using HTTPS protocol, you can adjust this as you see fit. This can easily be overriden by the site’s index.php file. I will explain this towards the end.

Also note that I disable auto updates for core and plugins. I use this on PRODuction so this shows you how I can globally disable these across all sites. If you don’t like that, go ahead and remove them. You only need to keep any that start with GLOBAL_WP_DEFAULT_.

In case this seems confusing, the file structure should be something like:

You can use the default WordPress config as normal for your site setup. The only difference is that you must define some constants for WordPress to work properly. Ideally, you can use the constants from the global wp-config.php. You can also add any other constants here that you want to be globally accessible between all sites.

This is all there is to setup the global directory of WordPress versions. Now let’s setup a site to use it.

 

 

Setup Website

For this, I will use www.domain.com for my example.

WordPress let’s you change the location of the wp-content directory, including plugins and themes. For this example, we are not going to fully customize these locations but instead keep the structure we all know. Keeping everything inside the wp-content directory.

To create your website, you will need to create:

  • index.php
    • The official site messes up the subdirectory installation. All you need to do is use the default index.php that comes with WordPress and add the subfolder to it.
      • No need to modify anything else. Seriously… not sure why the official site misses this one simple method to install in a subdirectory.
    • This is what the index.php should be, assuming you used wordpress for the WordPress subdirectory.
    • <?php
      /**
       * Front to the WordPress application. This file doesn't do anything, but loads
       * wp-blog-header.php which does and tells WordPress to load the theme.
       *
       * @package WordPress
       */
      
      /**
       * Tells WordPress to load the WordPress theme and output it.
       *
       * @var bool
       */
      define('WP_USE_THEMES', true);
      
      /** Loads the WordPress Environment and Template */
      require( dirname( __FILE__ ) . '/wordpress/wp-blog-header.php' );
      

       

  • wp-config.php – Make sure to add the edits below for this to work.
  • wp-content – Directory with it’s subfolders plugins and themes
    • This is not to be confused with the wp-content that is inside the WordPress version directory.

For beginners, you can just copy the contents of the WordPress wp-content but the point here is that your code should be isolated from WordPress in the first place.

Ideally, you would create the wp-content directory with it’s subfolders plugins and themes. Make sure to keep the index.php here as it’s just a security measure if you have directory listing enabled.

Install your plugins and themes into these directories respectively.

Next, let’s configure your wp-config.php so you can use the global version of WordPress.

You can use the sites wp-config.php as normal, you just need to make sure you use these constants in each site:

define('WP_SITEURL', 'https://' . $_SERVER['SERVER_NAME'] . '/wordpress'); // needed because WordPress is in a subdirectory
define('WP_HOME',    'https://' . $_SERVER['SERVER_NAME']); // Main site URL
define('WP_CONTENT_DIR', GLOBAL_WP_DEFAULT_WP_CONTENT_DIR); // Inherited from the global config
define('WP_CONTENT_URL', GLOBAL_WP_DEFAULT_WP_CONTENT_URL); // Inherited from the global config
// Custom optional config settings
// Prevent file editor
define('DISALLOW_FILE_EDIT', GLOBAL_WP_DEFAULT_DISALLOW_FILE_EDIT); // global option being implemented

For novices, put this under your database constants.

Again, note the HTTPS protocol in the constants. Change if you are not using the HTTPS protocol.

Now that the config is done, we want to add WordPress to the site. For this, we just have to create a symlink. You can create a symlink for the version 4.9.4 of WordPress by running:

Linux:

ln -s /path/to/Home/wordpressVersions/4.9.4 /path/to/Home/www.domain.com/public/wordpress

Windows:

mklink /D /path/to/Home/wordpressVersions/4.9.4 /path/to/Home/www.domain.com/public/wordpress

This is the real power behind this setup. For every site you have that needs wordpress, you just have to add a symlink. When you update WordPresss, it’s as easy as deleting then adding the symlink for the new version. There are numerous different ways you can use this setup. For me, this has been the most beneficial and it allows me to rollback very easily if an upgrade goes wrong.

Your site should now look something like:

If all goes well, your site is now up and running. Go ahead and try with another site to see the true power behind this setup.

Spread the love

Leave a Reply