4

I have split a WordPress blog into multiple category-specific blogs using subdomains, as the topics in the original blog were too broad to be lumped together effectively.

Posts were exported from the parent www blog and imported into the subject-specific subdomain blogs.

I believe .htaccess provides mod rewrite for all subdomains (including the original www) in a single .htaccess file.

I use .htaccess to perform 301 redirect on post categories to the relevant post on the subdomain's blog e.g.:

RedirectMatch 301 ^/auto/(.*)$ http://auto.example.com/$1

The problem I have is that the category has been retained in the permalink structure in the subdomain blog, so that www.example.com/auto/mercedes is now auto.example.com/auto/mercedes.

The 1st URL is redirect to the 2nd, but unfortunately, the 2nd URL is redirected to auto.example.com/mercedes using the same rewrite rule, which is not found, as the permalink on the subdomain's blog retains the parent category of auto.

The solution would be to adjust the permalink structure in the subdomain's WP settings, so that the top level category does not duplicate the subdomain.

My question would be: how do I then strip a section of the original (www) blog's post URL from the subdomain's URL when redirecting? e.g.: how do I redirect www.example.com/auto/mercedes to auto.example.com/mercedes?

I'm assuming this would be a regular expression trick, which I am not great at.

Update: I might have to use:

RewriteCond %{HTTP_HOST} !auto.example.com$

In the default WordPress if loop in .htaccess, and seperate my custom subdomain redirections into a second if loop section.

2 Answers 2

1

In ten lines you've got not only what you asked for, but a huge benefit: when you'll want you add a subject e.g "newsubject", just add a line in your map file:

newsubject newsubject

recreate the hash file, restart the server and here you go!!


So here's the "compressed" version:

 RewriteMap mapsubdomains \
   dbm:/web/htdocs/mysite/rewriterules/mapsubdomains.map
 RewriteCond %{HTTP_HOST} (([a-zA-Z0-9\-]+)\.)([a-zA-Z0-9\-]+)\.com$
 RewriteRule (.*) - [QSA,E=PART1:${mapsubdomains:%1|notfound}]
 RewriteCond %{ENV:PART1} ^$ [OR]
 RewriteCond %{ENV:PART1} notfound
 RewriteRule ^/([a-zA-Z]+)/(.*)$ - [QSA,E=SUBJECT:${mapsubdomains:%1|notfound}]
 RewriteCond %{ENV:SUBJECT} !^$
 RewriteCond %{ENV:SUBJECT} !(notfound)
 RewriteRule ^/([a-zA-Z]+)/(.*)$ http://%{ENV:SUBJECT}.mysite.com/$2 [QSA,L]

Detailed answer:

(1) use a map file where you'll write simple stuff like this:

auto    auto
moto    moto

then include it in your rewrite rule:

 RewriteMap mapsubdomains \
   dbm:/web/htdocs/mysite/rewriterules/mapsubdomains.map

then make a generic rule:

 RewriteCond %{HTTP_HOST} (([a-zA-Z0-9\-]+)\.)([a-zA-Z0-9\-]+)\.com$
 RewriteRule (.*) - [QSA,E=PART1:${mapsubdomains:%1|notfound}]

The previous rule means: if the hosts has two parts (e.g. http://part1.part2.com) then look in the mapsubdomain and fill it with the right value or "notfound" if not found.

Then if "notfound" this means you can check for the URL:

 # if PART1 empty:
 RewriteCond %{ENV:PART1} ^$ [OR]
 # ...or PART1 not found:
 RewriteCond %{ENV:PART1} notfound
 # ...then lookup: 
 RewriteRule ^/([a-zA-Z]+)/(.*)$ - [QSA,E=SUBJECT:${mapsubdomains:%1|notfound}]

 # if subject not empty, and is found then redirect:
 RewriteCond %{ENV:SUBJECT} !^$
 RewriteCond %{ENV:SUBJECT} !(notfound)
 RewriteRule ^/([a-zA-Z]+)/(.*)$ http://%{ENV:SUBJECT}.mysite.com/$2 [QSA,L]
1
  • This won't work in an .htaccess file, which the OP says they're using. Mar 13, 2012 at 21:46
1

Wow, that's a pretty complicated answer. This is how I would do it in an .htaccess context:

RewriteEngine On
RewriteBase /

RewriteCond %{HTTP_HOST} =example.com     [NC,OR]
RewriteCond %{HTTP_HOST} =www.example.com [NC]
RewriteRule ^(auto|foo|bar)/(.*)$ http://$1.example.com/$1/$2 [NS,L,R=301]

The RewriteConds ensure that this rule is only applied for example.com and www.example.com, not for any other sites. You can remove the first RewriteCond if you only want the rule to apply to www.example.com.

The RewriteRule then redirects e.g. www.example.com/auto/mercedes to auto.example.com/auto/mercedes. (If you want it to redirect to just auto.example.com/mercedes, replace $1/$2 with just $2.) The example also does the same for the categories foo and bar; you can add as many categories as you wish just by editing the regexp.

4
  • This just implies that there are a few words in (auto|foo|bar), otherwise after ~20 - ~50 words this becomes absolutely no maintanable. My solution sounds complicated, but it works flawlessly whatever the number of categories. But you got a point: if there are a few categories, your solution is better. Mar 14, 2012 at 8:39
  • Well, having lots of categories does give you a long line (I wish there was a way to wrap RewriteRules over multiple lines), but it doesn't otherwise make it any more complex or hard to maintain. It's just a pipe-delimited list of words; that's not fundamentally any less maintainable than a newline-delimited list in a map file. (Besides, since this is supposed to be for legacy URLs, there should be no need for maintenance anyway: you write it once, test it, add a comment saying what it does and never touch it again.) Mar 14, 2012 at 11:03
  • But I do agree with you on a general level: rewrite maps are neat and efficient, and I wish they'd work in .htaccess context too. I just think they're probably overkill for the OP's needs (and, anyway, they said they need a solution that works in an .htaccess file). Mar 14, 2012 at 11:08
  • So... your solution is better. Mar 14, 2012 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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