Rewritecond
You must use the directive RewriteCond
to add conditions to apply or not redirect.
For example:
# Redirect when we have a single parameter
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/$ index.php?mod=$1
In this case, the flags !-f
and !-d
are determining that the redirect will only occur if there is no file or folder with the corresponding url.
Syntax
The syntax of the command is:
RewriteCond TestString CondPattern
Where CondPattern
is a REGEXP perl compatible, with a few additions.
You can prefix Pattern with !
to reverse its effect. There are some variations that allow using the CondPattern
without REGEXP also:
'<CondPattern'
'>CondPattern'
'=CondPattern'
These last three treat the CondPattern
literally as a string, and compare respectively to TestString
with the literal value of CondPattern
See some more conditions:
-d
Take the result of TestString
and checks if it is an existing directory
-f
Take the result of TestString
and checks if it is an existing file
-s
Does the same as the -f
, but only considers non-empty files
-l
Checks whether the result of TestString
is path to a symbolic link
-x
Checks whether the result of TestString
is a path with +x permission
-F
Equals to -f
, but does a test to see if the file is really accessible by Apache. This implies making an extra internal request on the test, beware of overuse.
-U
Even if the -F
, but tests by URL and not Path
All these tests can be denied with a !
at first.
Applying to the practical case
A possible solution to address the question:
RewriteCond %{HTTP_HOST} ^cdn\.meusite\.com\.br$ [NC]
RewriteRule ^([a-z0-9_-]*)(/([a-z0-9_-]*))?(/([0-9]*))?(/)?$
cdn/index.php?mod=$1&call=$3&id=$5 [NC,L]
RewriteCond %{HTTP_HOST} ^app\.meusite\.com\.br$ [NC]
RewriteRule ^([a-z0-9_-]*)(/([a-z0-9_-]*))?(/([0-9]*))?(/)?$
app/index.php?mod=$1&call=$3&id=$5 [NC,L]
RewriteRule ^([a-z0-9_-]*)(/([a-z0-9_-]*))?(/([0-9]*))?(/)?$
index.php?mod=$1&call=$3&id=$5 [NC,L]
Don’t break the lines in Rewriterule! I broke the example just for readability.
Note that the latter case is more complex and we use some more advanced things:
- We used the flag CN (nocase) for case and lower case treatment
- We used the flag L (last) not to process the rest of the rewrite if any of the conditions are met
- Instead of three different lines to meet one, two or three parameters, we solve with one, transforming parameters two and three and the final bar into options using
( )?
us regex. This meant changing the group numbers to $1
, $3
and $5
in the output string.
- Read the documentation about the flags NE and QSA if you are having problems with query strings not behaving well, or if beyond the parameters mod, call and id need other provided directly by the pages.
Applying file and directory exceptions in the initial example:
# Redirect when we have a single parameter
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)$ index.php?mod=$1
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/$ index.php?mod=$1
# Redirect when we have two parameters
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ index.php?mod=$1&call=$2
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/$ index.php?mod=$1&call=$2
# Redirect when we have three parameters
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([0-9]+)$ index.php?mod=$1&call=$2&id=$3
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([0-9]+)/$ index.php?mod=$1&call=$2&id=$3
Note that in this case we had to repeat the RewriteCond
, For he is worth only to the first RewriteRule
what to find ahead.
The idea of this answer was to show a solution pertinent to the question. The mod_rewrite
is a bit complex to deal with all the details, so the ideal is really read the documentation.