Hierarchical file systems, directories and subdirectories

WordPress: Transform Your Experience with Subdirectories

Most of us are familiar with files, directories, and subdirectories.   In the art of computer science, directories are a way to organize files into a meaningful hierarchy.  WordPress relies on hierarchical file systems to organize the thousands of required files in a WordPress instance.

History lesson! Hierarchical file systems were introduced in Microsoft’s world with DOS 2.0!

When installing WordPress, it is reasonable to place the installation itself into a subdirectory instead of in the primary web accessible directory (often called “./public_html/”). It is easier to manage the WordPress installation if installed in a simple subdirectory such as “/wp/”.  Ease of maintenance is especially important when you are faced with something as drastic as a reinstallation.  It is also just a whole lot cleaner, and you can even install multiple WordPress instances on your domain this way.

Steps involved with deploying in a Sub-directory

Deploying WordPress in a sub-directory is straightforward.  Follow these steps for success.

Note that this article expects using https on the entire site, and also expects the domain to be hosted on www.

1. Create a “test” index.htm

This file is going to protect you against casual drivebys and users who land on your domain while you are creating the WordPress instance.

Create “index.htm” in the primary HTML directory (for example, in my Linux hosted sites, the location is public_html). Place whatever context you wish to have these temporary users to see (for example, “Come back soon!”), or just leave the file blank. HTML markup is not required.

TEST: Navigate to www.yourdomain.com . The index.htm text should be displayed.

TEST HTTPS: Navigate to https://www.yourdomain.com. The index.htm text should be displayed.

2. Modify .htaccess

Next, update the host environment to convert all domain access to www & https.  The hidden file .htaccess (note the dot (.) in front of the file .htaccess) is used to rewrite urls.  

While you are working in the .htaccess file, also make all requests convert to HTTPS if you have a certificate installed. If you don’t have a certificate installed, stop here and do this first!

Edit the .htaccess file (don’t forget the leading period) in your root domain directory (/) with the following code which will accomplish both tasks:

# Reference marksatterfield.com
# Setup ./index.php & https://www

DirectoryIndex index.php index.htm

# This strips off any subdirectories so the index.php is located properly.
<IfModule mod_rewrite.c> 
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# BEGIN Rewrite HTTPS/WWW
# IFCond not HTTPS or not WWW THENRule rewrite with both https & www

<IfModule mod_rewrite.c> 
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R=301]
</IfModule>

TEST: Test your site by navigating to http://domain.com , https://domain.com, and http://www.domain.com . Each of the three should land on https://www.domain.com and display the index.htm file created above.

3. Install WordPress in Sub-directory

Now install WordPress itself in a sub-directory.  Let’s say you choose “wp” as your WordPress installation directory.  In the first step, we’ve made sure to mask casual access to the main URL by way of index.htm. Visitors will be presented with the index.htm message instead of a directory listing.

TEST: Test your site by navigating to https://www.domain.com/wp (or whatever your site and subdirectory are called).

4. Update ~/index.php

Next, copy the ~/wp/index.php file from your working directory to ~/index.php (remember to copy, do not move). Then Add the /wp/ subdirectory to the appropriate ‘require wp-blog-header.php’ line. The final version will look something like this example.

<?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__ ) . '/wp/wp-blog-header.php' );

TEST: Test your site by navigating to domain.com . The url should automatically rename to https://www.domain.com/ and WordPress should start.

5. Change WordPress engine

Before we take this step, go to your URL.  The URL has been modified by .htaccess to include the subdirectory in the URL itself.  This is not likely what you wanted.  The last step is to clean up your URL.

Log into WordPress, go to the following:
WordPress >> Settings >> General

You will notice two URLs,

  • WordPress Address (URL), https://www.yourdomain.com/wp
  • Site Address (URL), https://www.yourdomain.com/wp

Change the Site Address to https://www.yourdomain.com (that is, remove any sub-directory information listed). Leave the WordPress address exactly as it is, with the subdirectory attached.

TEST: Test your site by navigating to domain.com . The site homepage should come up. Now also test navigating to all the pages and posts on your site. All navigation should be working fine, completely intact.

Congratulations!

You are all done!  Happy WordPressing!

Notes

Here is a version of the .htaccess rewrite rules that perform the https & www functions separately:

# BEGIN Convert to www & https access

DirectoryIndex index.php index.htm

# This strips off any subdirectories so the index.php is located properly.
<IfModule mod_rewrite.c> 
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress - host from subdirectory modifications


# BEGIN Convert *:// to https://
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# END Convert *:// to https://

# BEGIN add www to naked domain
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]                    

</IfModule>

Reference documents

  1. “Apache redirect www to non-www and HTTP to HTTPS”, https://simonecarletti.com/blog/2016/08/redirect-domain-http-https-www-apache/
  2. “Giving WordPress Its Own Directory”,
    https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory#Pointing_your_home_site.27s_URL_to_a_subdirectory
  3. “Changing The Site URL”,
    https://codex.wordpress.org/Changing_The_Site_URL
  4. “Non WWW To WWW Redirect With HTACCESS”, https://techstream.org/Web-Development/HTACCESS/WWW-to-Non-WWW-and-Non-WWW-to-WWW-redirect-with-HTACCESS
  5. “RewriteRule Flags”,   http://httpd.apache.org/docs/current/rewrite/flags.html#flag_e
  6. “Mod_Rewrite Variables Cheatsheet”,  https://www.askapache.com/htaccess/mod_rewrite-variables-cheatsheet/
  7. Protecting wp-login.php
  8. WordPress security Plugins
  9. Managing multiple WordPress sites