I've been trying for hours and am already a bit on the edge about this, so I am probably not seeing the obvious.

I have two WordPress sites, one is my "main" page which people see when they come to my domain root, and one is a private blog:

www.example.com and www.example.com/blog

On my server root, I would like to keep both pages organized in separate folders, to keep it clean. These folders I named wp-main and wp-blog. To redirect the domains I started fiddling with .htaccess, but I can't seem to get it right - blog is the problem. main works fine with instructions from here, but the blog doesn't load the WordPress theme (displays raw content), and does not redirect to any subfolders. If I take away the redirect rules for main, the blog index gets loaded, but still no subfolder redirect.

Can anybody help me out here?

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /

## redirect for main
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/wp-main($|/)$
RewriteCond %{REQUEST_URI} !^/blog($|/)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /wp-main/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ wp-main/index.php 

## redirect for blog
RewriteRule ^blog(.*)$ /wp-blog/$1
  • Do you have more than one domain? – MrWhite Feb 28 at 0:50
  • sorry, I missed that earlier - it's only one domain – mluerig Mar 2 at 9:49
RewriteCond %{REQUEST_URI} !^/wp-main($|/)$
RewriteCond %{REQUEST_URI} !^/blog($|/)$

You should remove the $ (end-of-string anchor) at the end of these two CondPatterns. Otherwise, requests for /blog/<something> will get routed to /wp-main/..., since the above condition is satisfied (since it does not match the pattern ^/blog($|/)$).

Consider reversing your logic and rewrite /blog (the more specific URL) first. (And use L flags to prevent additional processing.)

UPDATE: Try the following instead...

I've reversed the logic, so that /blog is handled first (the more specific URL). This avoids you having to explicitly avoid /blog when rewriting the main site. I've also assumed that you only have one domain (which I asked about in my earlier comment) - this avoids the requirement to check the Host header (ie. HTTP_HOST server variable). If you do have more than one domain on your account then your current directives were incomplete anyway.

You do not need the <IfModule mod_rewrite.c> wrapper, unless your site is intended to function without mod_rewrite (it is not).

Potentially, all you need is:

RewriteEngine on

# Rewrite blog site
RewriteRule ^blog/?(.*)$ /wp-blog/$1 [L]

# Rewrite everything else to the main site
RewriteRule (.*) /wp-main/$1 [L]

A few assumptions:

  • Each subdirectory (/wp-blog and /wp-main) has its own .htaccess file (with mod_rewrite directives) - this prevents a rewrite loop.

  • There are no static resources outside of these WordPress installations. All static resources are also rewritten. eg. /images/foo.jpg is internally rewritten to /wp-main/images/foo.jpg and /blog/images/foo.jpg is rewritten to /wp-blog/images/foo.jpg etc. You never reference /wp-main or /wp-blog directly in client-side HTML. If there are shared static resources in other locations (eg. a /scripts subdirectory off the real document root) then you will either need an additional filesystem check (if there are too may locations to list) or include an exception for this location, before the existing directives. For example:

    RewriteRule ^scripts/ - [L]
  • Both /blog and /blog/ (with a slash) access your blog homepage (this avoids /blog being rewritten to your main site). Ideally, only /blog/ should access your blog and /blog would redirect to this. This can be achieved with an additional redirect before the blog rewrite:

    # Rewrite blog site
    RewriteRule ^(blog)$ /$1/ [R=302,L]
    RewriteRule ^blog/?(.*)$ /wp-blog/$1 [L]

    Change the 302 (temporary) to 301 (permanent) only when you are sure this is what you want and have confirmed that it works OK. 301s are cached persistently by the browser.

Then, each .htaccess file in the respective subdirectory should be of the form:

RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

No need to specify the RewriteBase or include the subdirectory in the RewriteRule substitution.

  • Thanks! Now blog and its index display correctly. I put RewriteRule ^blog(.*)$ /wp-blog/$1 [L] after RewriteBase /. However, what is still not working is the subfolder redirect for blog: if I click on one of my blogposts, I end up with "Page not found", but in the main layout. Any guess? – mluerig Feb 28 at 8:56
  • "the subfolder redirect for blog" - I'm not sure what you mean? Have you changed the URL structure in WordPress itself to reference /blog/....? – MrWhite Feb 28 at 11:49
  • what I mean was that if I click on anything that goes beyond /blog/ (e.g. "mydomain.net/blog/entry1" in the url, I end up with a "Page NOT Found" error. the error is displayed as part of the main-wordpress page. does that make sense? – mluerig Mar 1 at 13:32
  • RewriteRule ^blog(.*)$ /wp-blog/$1 [L] - This will result in a double slash in the rewritten URL, which could be a potential problem, although this shouldn't result in the request appearing on the "main" site? What do you have in the subdirectory/WordPress .htaccess files? I've updated my answer. – MrWhite Mar 1 at 23:08
  • 1
    sweet, that did it, many thanks for your answer! indeed, there are some shared files between the sites. I added RewriteRule ^(wp-shared|wp-files)($|/) - [L] before the rules in the root htaccess regarding your last point (/blog or /blog/ taking me to the "blog" site), this already worked without me specifiying this anywhere... – mluerig Mar 2 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.