Reputation: 353
# /.htaccess
RewriteEngine on
RewriteBase /
RewriteRule "^([^/]+)/root/(.*)" "$1/index.php?root=$2"
# /folder/.htaccess
RewriteRule "^sub/(.*)" "index.php?sub=$1"
Each folder's RewriteRule
works in isolation:
/folder/root/hi => /folder/index.php?root=hi
/folder/sub/hello => /folder/index.php?sub=hello
Q: Why does adding any RewriteRule
in the subfolder (/folder/.htacces
) break the one in the web root (causes 404)? What do I need to do to create rules on different levels?
I've tried adding RewriteOptions Inherit(Down)
, but that didn't have any effect.
Upvotes: 1
Views: 337
Reputation: 1340
With Apache 2.4, I've success by adding RewriteOptions InheritDownBefore
in the parent .htaccess
.
Upvotes: 0
Reputation: 45914
Assuming you have RewriteEngine On
in the /folder/.htaccess
then the mod_rewrite directives in the parent config will be completely overridden, since mod_rewrite directives don't inherit by default.
However, even if you enable mod_rewrite inheritance, the directives still won't work, because mod_rewrite inheritance "virtually copies" the directives "in-place", as if the directives are in the same config file - in the same scope (with the same directory-prefix).
So, with RewriteOptions Inherit
in the /folder/.htaccess
file, the directives are effectively processed like this:
# /folder/.htaccess
RewriteRule "^sub/(.*)" "index.php?sub=$1"
# Inherited from parent config
RewriteRule "^([^/]+)/root/(.*)" "$1/index.php?root=$2"
The pattern "^([^/]+)/root/(.*)"
simply won't match if used in the scope of the /folder/.htaccess
file - which is what's happening when using mod_rewrite inheritance.
IF the /.htaccess
(root) directives are always inherited then you could modify the root directive to read something like the following (removing the parent directory from the rule):
RewriteRule ^root/(.*) index.php?root=$1 [L]
(Yes, it matches the directive already in the /folder/.htaccess
file.)
However, the "problem" now is that directive probably won't work if not inherited as in your example. IF you specifically need it to work in both scenarios: when inherited from a subdirectory .htaccess
file and directly from the document-root, then modify the directive to make the parent folder optional. For example:
RewriteRule ^([^/]+/)?root/(.*) $1index.php?root=$3 [L]
You may still need to fix the RewriteBase
directive, or remove it altogether.
mod_rewrite inheritance is not as useful as it at first appears. Directives - that are expected to be inherited - generally need to be specifically written to allow for this.
Upvotes: 1
Reputation: 785631
You need to change your root .htaccess rule to this:
RewriteRule ^([^/]+/)?root/(.*)$ $1index.php?root=$2 [L,QSA]
This is to make initial part [^/]+/
an optional match in order to make same rule work from root .htaccess as well as from a /folder/.htaccess
.
Then have this in your folder/.htaccess
:
RewriteOptions Inherit
RewriteEngine On
RewriteRule ^sub/(.*)$ index.php?sub=$1 [L,QSA]
RewriteOptions Inherit
will inherit all rules and directives from parent .htaccess and will apply them in child's context after applying all the rules defined in child .htaccess.
Upvotes: 1