Search code examples
regexapache.htaccessmod-rewritemulti-level

.htaccess rewrite multi-level sub-directory exception


I've been using an .htaccess script for clean URLS on my servers using my own custom CMS:

# this is the initialization
Options         +FollowSymLinks
RewriteEngine   On
RewriteBase     /
# these are the rewrite conditions
RewriteCond     %{REQUEST_FILENAME}     !-f
RewriteCond     %{REQUEST_FILENAME}     !-d
# and finally, the rewrite rules
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$   /pages.php?which_page=$1&data1=$2 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6&data6=$7 [L,QSA]

This works great at redirecting all requests to the pages.php script of my CMS.

The problem is that on rare occasion I have a client that wants to add a sub-directory in which they can add unlimited additional sub-directories all of which need to be redirected to index.html within them. For this discussion lets call this primary sub-directory main-dir which when a user goes to www.mysite.com/main-dir should re-direct them to www.mysite.com/main-dir/index.html

If the client adds more directories in main-dir the direction should be to an index.html within them E.g. www.mysite.com/main-dir/some-dir/index.html

So essentially I need to exempt main-dir and any of it's sub-directories from the regular pages.php redirect and make certain they all redirect to index.html within them.

I've tried a whole host of things to accomplish this including adding an .htaccess file in the sub-directory with only RewriteEngine off and adding various conditions and rules such as:

RewriteCond %{REQUEST_URI} !^/collections/^

and

RewriteRule ^(collections)/$1 [L]

Nothing has worked.

currently if a web user goes to www.mysite.com/main-dir they are re-directed to the pages.php script and not exempted although if they go to www.mysite.com/main-dir/index.html they do get to the html page.

Any assistance would be appreciated.


Solution

  • You have to just make use of negative lookahead in every RewriteRule like this:

    # ignore all rules if URI starts with /main-dir/
    RewriteRule ^main-dir/  - [L,NC]
    
    RewriteRule ^([\w\s+-]+)/?$ pages.php?which_page=$1 [L,QSA]
    
    RewriteRule ^([\w\s+-]+)/([\w\s+-]+)/?$ pages.php?which_page=$1&data1=$2 [L,QSA]
    
    RewriteRule ^([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/?$ pages.php?which_page=$1&data1=$2&data2=$3 [L,QSA]
    
    RewriteRule ^([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/?$ pages.php?which_page=$1&data1=$2&data2=$3&data3=$4 [L,QSA]
    
    RewriteRule ^([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/?$ pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5 [L,QSA]
    
    RewriteRule ^([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/?$ pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6 [L,QSA]
    
    RewriteRule ^([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/([\w\s+-]+)/?$ pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6&data6=$7 [L,QSA]
    

    That will make above rules applicable for everything except /main-dir/.

    Also for serving index.html inside /main-dir/ you don't need to do anything since that is shown by default in Apache.