Search code examples
.htaccessmod-rewriteurl-mapping

.htaccess map subdirectory as root


I found a question similar to this but doesn't seem to work for me ( Make web root folder a sub-folder with .htaccess?). So i'm asking for help after not being able to find any answers to my problem -- i spent 2 hours going through 200+ pages of results on stackoverflow before giving up. Anyways...

I'm creating a small CMS and have my directory structure setup like this:

application
-- html
-- -- public
-- -- -- theme
-- -- -- -- css
-- -- -- -- images
-- -- -- -- js
-- -- -- forum
-- -- -- -- index.php
-- -- -- -- viewforum.php
-- -- -- -- viewthread.php
-- -- -- -- comment.php
-- -- -- index.php
-- -- -- login.php
-- -- -- profile.php
-- -- admincp
-- -- -- theme
-- -- -- -- css
-- -- -- -- images
-- -- -- -- js
-- -- -- index.php
-- -- -- manage.php
-- -- -- users.php
-- -- -- settings.php
-- plugins
library

What I'm trying to accomplish is to map mydomain.com/application/html/public/index.php to mydomain.com/index.php and with admincp its mydomain.com/admincp/index.php. So that it looks like everything in the public directory is located in the root directory.

At the moment when i view mydomain.com it shows the index.php file from ../public/ but when i try mydomain.com/index.php i get a not found error. When I go to mydomain.com/admincp or mydomain.com/admincp/manage.php it works though-- if you know of a way of making it better let me know. :)

RewriteEngine on
RewriteRule ^$ application/html/public/
#RewriteRule ^(.*)$ application/html/public/$1 # Breaks site

RewriteCond  %{DOCUMENT_ROOT}/admincp  !-f
RewriteRule ^admincp/(.*)? application/html/admincp/$1
RewriteRule ^admincp$ admincp/ [L]

I'd appreciate any help,advice, sarcasm that I can get on this issue.

-- EDIT --

@Michael provided me with an answer that served my purpose This was the result:

RewriteEngine on
# Don't need this...
#RewriteRule ^$ application/html/public/

# Need [L] and a RewriteCond
# Don't do the rewrite if this is an actual existing file
# such as what is rewritten into application/html/public
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# And don't write admincp into public
RewriteCond %{REQUEST_FILENAME} !admincp
# With the above conditions met, write anything else into the public dir
RewriteRule ^(.*)$ application/html/public/$1 [L]

# Then just write admincp into application/html/admincp
RewriteRule ^admincp/(.*) application/html/admincp/$1 [L] 

Now I just need to fix the problem where my directory index is displayed when viewing the root -- mydomain.com/

-- EDIT --

When i added back in RewriteRule ^$ application/html/public/ It didn't break, so its lookin like it works like it should!


Solution

  • A missing [L] flag and a rewrite loop when public/ is matched, is likely the cause of your site breaking. The first of your two rules for the public area is unnecessary if the second is done correctly:

    RewriteEngine on
    # Don't need this...
    #RewriteRule ^$ application/html/public/
    
    # Need [L] and a RewriteCond
    # Don't do the rewrite if this is an actual existing file
    # such as what is rewritten into application/html/public
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    # And don't write admincp or others into public
    
    # Add each area you need to exclude into the () below
    RewriteCond %{REQUEST_FILENAME} !(admincp|formus|otherarea1|otherarea2)
    
    # With the above conditions met, write anything else into the public dir
    RewriteRule ^(.*)$ application/html/public/$1 [L]
    
    # Then just write admincp into application/html/admincp
    #RewriteRule ^admincp/(.*) application/html/admincp/$1 [L]
    # Update: Instead of the above rule, if you need additional rules like forums
    # make the final rule generic to capture the directory in ([^/]+):
    RewriteRule ^([^/]+)/(.*) application/html/$1/$2 [L]