Forum Moderators: phranque
http://example.com/main/page.html
results in loading the page
/home/site/public_html/main/page.html
However the "main" directory has only recently been inserted into the structure to segregate the files in and below it from lots of other files in another area. The /main files are really top-level files, but must be kept separate for edit-access purposes.
So, to access .../main/page.html I need to rewrite all requests for the top-level URL (and any levels below it except main) from
http://example.com/page.html
to get the newly-situated file at
http://example.com/main/page.html
I have seen documentation describing "rewrite URL to subdirectory", but I can't get the suggested rule to work. It is probably due to me misunderstanding something cPanel has put somewhere, but I am not sure. I currently have my .htaccess file at
/home/site/public_html/.htaccess
I expected that I might have recursion problems, but that doesn't seem to happen.
Any ideas would be much appreciated.
Thanks
[edited by: jdMorgan at 11:29 pm (utc) on May 24, 2008]
[edit reason] use example.com, no sigs, please. [/edit]
Please post your best-effort [webmasterworld.com] code, and let us know where you're putting it -- httpd.conf, conf.d, .htaccess etc.
Thanks,
Jim
RewriteEngine on
# Force index if homepage
RewriteRule ^/$ http://example.com/main/index.html [R=302,L]
# Check for file at subdirectory level, if present exit:
RewriteCond main/%{REQUEST_FILENAME} -f
RewriteRule ^(.+) $1 [L]
# If it wasn't, rewrite to subdirectory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+) http://example.com/main/$1 [R=302,L]
It seems to work if the URL includes an actual filename, but a request for the homepage does not load http://example.com/main/index.html as would be expected from the first rule. I presume this because the default filename is in some way conflicting with mod rewrite (or I misunderstood the "processing sequence" information). One gets the home directory listing.
If the file does not exist, it loops adding /main multiple times.
Also, it is rewriting the browser URL, which I want to avoid - I seem to have confusing documentation about rewrite as opposed to redirect!
I am still experimenting, but I had thought this was a pretty standard need.
Your first rule: In .htaccess, the path to the current directory is stripped from the URL-path seen by RewriteRule. This is because .htaccess is a per-directory configuration, so all paths are "localized" to the current directory. In practical terms here, this means that the leading slash will not be present on URL-paths examined by RewriteRule in example.com/.htaccess
Your second rule: From what I can tell, this rule was redundant, since the "file exists" check is also done by your third rule. I removed your second rule, because "file exists" checks are CPU intensive, and may require an actual read of the file-directory information from the disk, which is *very* slow.
Your third rule: In .htaccess, you must explicitly prevent looping. I added a check to be sure we had not already rewritten the request to the /main subdirectory. Note that this check is done before the "file exists" check, to prevent that "exists" check from wasting time/CPU if it's not necessary (for the reasons stated above).
# Internally rewrite to index file if homepage URL-path requested
RewriteRule ^$ /main/index.html [L]
#
# If not already rewritten to subdirectory, and requested URL-path does not resolve
# to an existing file, internally rewrite the request to the /main subdirectory
RewriteCond $1 !^main/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /main/$1 [L]
A 301 redirect would have been better, but you really don't want or need for the user to see the "/main/" in the URL. That's internal implementation stuff that the user does not need to see.
The rewrite is the best thing. It silently connects an external URL request to a different internal filepath.