Forum Moderators: phranque

Message Too Old, No Replies

Htaccess redirect subdomain folders in letter-directories

         

dienast

3:43 pm on Nov 2, 2011 (gmt 0)

10+ Year Member



Dear forumers,

Currently, when I create a directory in my root dir (public_html) then a subdomain is created and this works perfectly.

However, I am planning to create alot (possibly thousands) of subdomains and I want to keep it orderly. So what I want to do is to create in the root subdirectories for each letter, subfolders 'aa', 'bb', 'cc', ... 'zz'. In each letter-directory the corresponding subdomains much be present.

So public_html/aa/ has subdomains e.g 'angels', 'anger' etc..
And public_html/bb/ has subdomains e.g 'beach', 'butter' etc..

The htaccess below only works for only 1 directory, namely the subdomains in directory 'aa':

RewriteEngine On
RewriteBase /
RewriteCond %{ENV:REDIRECT_SUBDOMAIN} =""
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$
RewriteCond %{HTTP_HOST} ^([a-z0-9][-a-z0-9]+)\.example\.com\.?(:80)?$ [NC]
RewriteCond %{DOCUMENT_ROOT}/aa/%1 -d
RewriteRule ^(.*)$ aa/%1/$1 [E=SUBDOMAIN:%1,L]
RewriteRule ^ - [E=SUBDOMAIN:%{ENV:REDIRECT_SUBDOMAIN},L]

How can I make this dynamically for all letter-directory instead of only 1? I've tried allmost everything.

Kind regards,
Byron

lucy24

8:30 pm on Nov 2, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What is your second Rule intended to do? It doesn't have any attached conditions.

If the sub-subdirectories always start with the same letter as the subdirectory, as in your example, it should be trivial to express them all in a single ruleset. Just capture the first letter separately and proceed from there.

That's assuming all your requests are lower-case all along. If not, you'll have to detour via a php script or similar to regularize the casing.

You say you've tried "almost everything" so let's see some examples of what you've tried, along with a detailed explanation of what happens. ("It doesn't work" is not detailed.)

dienast

10:32 pm on Nov 2, 2011 (gmt 0)

10+ Year Member



The sub-subdirectories do not necessarily have to start with the same letter as the letter directory, but its only meant for order purposes, for me to keep an overview if I have thousands of subdomains.

Ok, an example of what I basically tried is:
RewriteCond %{DOCUMENT_ROOT}/([a-z]+)/%1 -d
RewriteRule ^(.*)$ /([a-z]+)/%1/$1 [E=SUBDOMAIN:%1,L]

Where ([a-z]+) should match every letter directory.

I know, it should be trivial, but I can not get it to work ;) so I hope someone could provide the answer for me..

dienast

2:59 pm on Nov 3, 2011 (gmt 0)

10+ Year Member



I got it working with the below htaccess:


RewriteEngine On
RewriteBase /
########## Letter A ###########
RewriteCond %{ENV:REDIRECT_SUBDOMAIN} =""
RewriteCond %{HTTP_HOST} !^(www\.)?linktrailer\.nl$
RewriteCond %{HTTP_HOST} ^([a-z0-9][-a-z0-9]+)\.linktrailer\.nl\.?(:80)?$ [NC]
RewriteCond %{DOCUMENT_ROOT}/aa/%1 -d
RewriteRule ^(.*)$ /aa/%1/$1 [E=SUBDOMAIN:%1,L]

... to ...

########## Letter Z ##########
RewriteCond %{ENV:REDIRECT_SUBDOMAIN} =""
RewriteCond %{HTTP_HOST} !^(www\.)?linktrailer\.nl$
RewriteCond %{HTTP_HOST} ^([a-z0-9][-a-z0-9]+)\.linktrailer\.nl\.?(:80)?$ [NC]
RewriteCond %{DOCUMENT_ROOT}/zz/%1 -d
RewriteRule ^(.*)$ /zz/%1/$1 [E=SUBDOMAIN:%1,L]

However, I presume that this can be done more dynamically.
So far I've tried to adjust the last RewriteCond and RewriteRule to 'catch' the letter-directories in one rewrite rule like Lucy suggested, with: ([a-z]+), or (.*) or (.+) etc.. but it didn't work. I've spend a couple of hours on this problem and I bet there is a more efficient method.

lucy24

7:25 pm on Nov 3, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What you want to do is capture the first letter separately: either as (([a-z])[-a-z0-9]+) or as ([a-z])([-a-z0-9]+) depending on personal taste. (The first way leads to using %2 in one place and %1 in the other. The second way uses $1 in one place and %1%2 in the other.) Once you've got the capture, that can become your directory name, like /$1$1/. Details depend on your exact structure.

But note again that if your input can be either upper- or lower-case, you will have to do something preliminary to make them all lower-case. Otherwise you'll be facing directories called either /AA/ or /aa/ and so on through the alphabet.

In your example, wouldn't %1 be "www." ?

dienast

1:44 pm on Nov 5, 2011 (gmt 0)

10+ Year Member



I'm sorry, but I did not fully understand your post. I expect that the only thing that should be editted is the fourth RewriteCond and the RewriteRule, namely:

RewriteCond %{DOCUMENT_ROOT}/aa/%1 -d

should be editted to, as you suggest:

RewriteCond %{DOCUMENT_ROOT}/%1%2/%1 -d

And the same counts for the RewriteRule, namely:

RewriteRule ^(.*)$ /%1%2/%1/$1 [E=SUBDOMAIN:%1,L]

However, this does not work. I have no idea how the RewriteCond and RewriteRule should look like to get this to work.

lucy24

10:42 pm on Nov 5, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm going to do this by analogy rather than figuring out your exact situation, because you'll be able to work out the details.

Suppose I had a bunch of directories-- /angels, /breadcrumbs, /doughnuts, /devils etc-- and I decide things are getting way too messy and I want to group them into subdirectories. So I create 26 subdirectories /aa through /zz, move the existing files, and now I only have to deal with requests for old-style filenames.

That means anything beginning in /a now goes to directory /aa and so on.

Do not use [NC] or you will get into a big mess.

Preliminary step:

RewriteRule ^([a-z0-9-]*[A-Z].*) http://www.example.com/fixup.php [L]


Capture anything containing a capital letter, rewrite to a php script that first fixes the capitalization and then redirects to the correct page. The redirect happens on the fixup page, so requests containing capital letters will not be seen in your htaccess again.

For anything that was correctly lower-case in the first place:

RewriteRule ^([a-z])([^/]{2,}.*)?$ http://www.example.com/$1$1/$1$2 [R=301,L]


The {2,} constrains your Redirect to requests that aren't already asking for a two-letter directory. Yes, there are three separate occurrences of $1 in the Redirect. The first pair is the new directory /aa /bb and so on. The second pair is the entire request.

Two-letter words are icky and messy. Two letters, followed by a directory slash or an extension or nothing. The Condition is supposed to ensure that those two letters are not the same. (Requests for "aardvark" are fine. Requests for "aa" are not. Do not allow your users to create subdomains pertaining to Danish islands.)

RewriteCond %{REQUEST_URI} !^/([a-z])($1)
RewriteRule ^([a-z])([a-z]([/.].*)?)$ http://www.example.com/$1$1/$1$2 [R=301,L]


I think I may detour and test all this in MAMP. It could be useful. Here I was just extrapolating from what I do in text files when there's a glossary that has to be keyed to the first letter of the word.