Forum Moderators: phranque

Message Too Old, No Replies

One .HTACESS File for multiple directories

Single .HTACESS file

         

Patchworks

12:08 am on Aug 16, 2012 (gmt 0)

10+ Year Member



Currently we use an .HTAcess file that looks like the one below. Basically now matter what page they request this .HTAcess file redirects them to index.php in the /Main directory.

What I want to be able to do is make sub-directories of /main but only a single .HTAcess file in /main directory. Any request to one of the sub-directories would redirect them to the index.php in the sub-directory that was requested.

Basically I wan to keep the directory they requested but redirect them to index.php without having to hardcode each sub-directory!


For example:

With a single .HTAcess in the /main directory if someone requests the following URL:

www.domain.com/main/sub1/anything.html

It would redirect to:

www.domain.com/main/sub1/index.php





Here is our current .HTAcess file

#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^([^/]+).html?$ /main/index.php?q=$1 [L]


RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\..+$
RewriteRule ^(.*)$ /main/$1.html [R=301,L]

lucy24

12:43 am on Aug 16, 2012 (gmt 0)

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



Holy ###. Is this the Question of the Week or what? I've never seen this so often as in the last few days. You need a RewriteCond looking at the...

Oh, wait.

When you say "subdirectories" do you mean subdomains, or do you really mean directories-- like www.example.com/directoryone/ and www.example.com/directorytwo/ ?

And do you mean that for any given directory, all requests get redirected to /directoryname/ ?

:: Sit on hands. Do not argue. Just show him how to operate the ### gun ::

Seems like a simple capture would do it, if so. What's the issue exactly?

incrediBILL

12:50 am on Aug 16, 2012 (gmt 0)

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



FYI, it won't work if you name it ".HTAcess", try ".htaccess" instead.

g1smd

1:37 am on Aug 16, 2012 (gmt 0)

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



If you really have to do this, do not redirect to a named index page. Redirect to folder URL ending in trailing slash.

However, there's a negative SEO effect once Google realises you're funnelling large numbers of URLs to one URL, and that your site is incapable of serving a 404 response.

If you still want to go ahead with this, then it just three lines of code.

Patchworks

5:16 am on Aug 16, 2012 (gmt 0)

10+ Year Member



Lucy24: Yes, I really mean Sub-Directory NOT DOMAIN! Are there other requests for this type of thing? I'll look in the forums. If you could point me to those threads I would appreciate it.

IncrediBill: Yes, I noticed that I mispelled .HTACCESS

G1SMD: For this application I not worried much about SEO. I just need the functionality.

lucy24

5:47 am on Aug 16, 2012 (gmt 0)

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



No, scratch that, it's subdomains that have been flooding the forums lately.

All your named pages are .html, and the index pages are .php? That makes it easier. Seems like all you'd need is

RewriteRule ^(([^/.]+/)*)[^/.]+\.html http://www.example.com/$1 [R=301,L]

and then your generic Rule (you'd have this one in any case)

RewriteCond %{THE_REQUEST} index\.php
RewriteRule ^(([^/.]+/)*)index\.php http://www.example.com/$1 [R=301,L]

The Condition is to avoid an infinite loop in case something goes screwy with mod_dir, whose job includes rewriting-- not redirecting-- directory requests to serve up the named index file.

Note that the content of the capture in Rule 1 may be null. That's for your top-level example.com directory. If you don't want redirects at this level, like
www.example.com/stuff.html
to
www.example.com/
change the * in the first pattern to + to force at least one level of subdirectories.

Patchworks

3:39 pm on Aug 16, 2012 (gmt 0)

10+ Year Member



lucy24, I tried this and it didn't work. I don't need it to work in the root and in fact it will always be 2 directories deep.

g1smd

7:32 pm on Aug 16, 2012 (gmt 0)

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



It didn't work

You'll need a better error report than that.

Use the Live HTTP Headers extension for Firefox to check out what happens.

lucy24

11:05 pm on Aug 16, 2012 (gmt 0)

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



in fact it will always be 2 directories deep

You mean two subdirectories? That is,
www.example.com/directoryone/directorytwo/{possiblymorestuff)
?

Then instead of

^(([^/.]+/)*)

you say

^(([^/.]+/)([^/.]+/)+)

or, if you want to be show-offy,

^(([^/.]+/){2,})

The opening anchor isn't absolutely necessary but will do no harm. (If you were searching for a maximum number of directories, like "no more than three", you would need an anchor to prevent the RegEx from ignoring part of the request.)

The . in the grouping brackets [^./] are also not technically necessary, since each group requires a following slash. But they make it all run a nano-something faster, because it saves one round of potential backtracking.

g1smd

11:22 pm on Aug 16, 2012 (gmt 0)

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



(([^/.]+/)([^/.]+/)+)
is ambiguous. With 3 folders, it's unknown whether $2 will contain 2 or 1 entries and $3 will contain 1 or 2 entries.

For a pattern like this, the start anchor is crucial. Without it, the first folders might not be captured at all.

Patchworks

11:48 pm on Aug 16, 2012 (gmt 0)

10+ Year Member



Lucy, I was planning on it always being 2 levels, but to have a 3rd level sub directory would be nifty for organization, but it would ABSOLUTELY NEVER BE MORE THEN 3 Sub Directories levels.

Ok so I made my file look like this:

RewriteRule ^(([^/.]+/)([^/.]+/)+) [^/.]+\.html http://www.domain.com/$1 [R=301,L] 

RewriteCond %{THE_REQUEST} index\.php
RewriteRule ^(([^/.]+/)*)index\.php http://www.domain.com/$1 [R=301,L]



It actually did a redirect but I think it redirected to the index.php in the root and not in the directory at the same level of the URL request.

I think we are on the right track though.

g1smd

12:24 am on Aug 17, 2012 (gmt 0)

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



The first rule also matches index requests. If you don't want that rule to affect index requests the index redirect must be listed first.

Order your redirects from "most specific" (affects the least number of URLs) to "most general" (affects the most number of URLs).

Patchworks

12:29 am on Aug 17, 2012 (gmt 0)

10+ Year Member



Ok, so I commented out the first request... I'm not e3ven sure exactly what it does...

But it still didn't work...

lucy24

7:42 am on Aug 17, 2012 (gmt 0)

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



I'm not even sure exactly what it does

Me neither. I think you may have cut-and-pasted too fast where I said "replace A with B". The pattern in Rule 1 should replace the pattern in Rule 2. But don't do it mechanically; look at what you're doing.

(([^/.]+/)([^/.]+/)+) is ambiguous. With 3 folders, it's unknown whether $2 will contain 2 or 1 entries and $3 will contain 1 or 2 entries.

In the present situation it wouldn't matter, because the only capture is $1-- the whole thing. And I think you may be reading it cross-eyed ;) The first two plusses apply only to the [^./] groups, not to the complete ([^./]+/) package. So it's "one mandatory directory, followed by at least one more". Hence the {2,} alternative.

Patchworks

4:47 pm on Aug 17, 2012 (gmt 0)

10+ Year Member



Lucy, I think you are making an assumption that I know what I'm doing and the truth is when it comes to HTAccess, I simply dont... I can run circles around SEO and other topics but HTACESS RegExp is not my thing.

The way to avoid confusion would be to post the complete file syntax instead of copy and paste this small section...

lucy24

9:31 pm on Aug 17, 2012 (gmt 0)

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



I think you are making an assumption that I know what I'm doing

And vice versa ;) But see boilerplate in some adjoining thread about "Why We Make You Do It Yourself".*

I've kinda lost track, but I think this was where we left off:

RewriteCond %{THE_REQUEST} /\w+\.(php|html)
RewriteRule ^(([^/.]+/)([^/.]+/)+)[^/.]+\.(php|html) http://www.example.com/$1 [R=301,L]

Meaning: If the user asks for any named file in a subdirectory, send 'em to the same subdirectory's index file. This includes explicit requests for the index.php file by name-- which is handy, because normally that would be a separate mopping-up redirect near the end of your rewrites.

The line looking at THE_REQUEST is necessary because a bit later on, mod_dir will come along and silently rewrite
directory/
to
directory/index.php

You don't want to go around in circles and you don't want the address bar to say "index.php". (If you know SEO you already know that part. A directory's name officially ends in a slash. If you allow the alternative /index.xtn you've got the dreaded Duplicate Content.)


* Except for the Title Case in that phrase. I do that with a keyboard shortcut. Heh.