For many years now I’ve had WordPress installed as a subdirectory to my site but appearing to at the domain level, i.e. /wordpress/index.php
is transparently presented as the homepage. This is done by setting the “WordPress Address” and “Site Address” settings and then mapping requests which do not match an existing file or directory through as a PHP pathinfo
using Apache’s mod_rewrite
rules in a .htaccess
file or server configuration.
In this way most of the site is WordPress’s dynamic pages and posts, but WordPress itself is neatly contained and random static resources such as /screentest/1024.GIF work as expected.
Those .htaccess
rules were originally hand-crafted but didn’t take account of changing recommendations, e.g. the Authorization
header. When I rearranged matters recently I decided to take advantage of WordPress’s own generated rules and ditch my old rules.
They look like this:
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
If .htaccess
is writable, WordPress adds these rules automatically. Unfortunately, when I switched to them and not my own, the site broke.
Crucially the generated rules do not cater for WordPress being in a subdirectory. No matter what combination of settings I tried, local changes to the rules (like RewriteRule . /wordpress/index.php [L]
) were rewritten back to the original values at random times and clearly couldn’t be relied upon to stay as I need them.
This feels like a bug: my intuition is that if the “WordPress Address” and “Site Address” settings are different, but within the same domain, the rules should be generated to take care of that.
One option is to make the .htaccess
file read-only, which WordPress detects and avoids trying to make changes at all. But this rather defeats the object of letting it take care of future changes as the software and specifications change.
The second option, which I stuck with, is to add an index.php
file with the following contents:
<?php
include('wordpress/index.php');
Now the generated rules, though incorrect, result in the right behaviour and won’t break on every setting change.