Multiple RewriteRules for single RewriteCond in .htaccess

Huseyin picture Huseyin · Aug 28, 2011 · Viewed 60.5k times · Source

I have following command in my .htaccess

    RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
    RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
    RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]

%2 is not working in second and later lines. Can I define any variable for %2 and use it in all RewriteRule commands? Following command works

     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]

But I want use %2 for multiple rule line without duplicating condition.

Answer

Jpsy picture Jpsy · Dec 19, 2012

You can use the RewriteRule flag S|skip to tie multiples RewriteRules to a single RewriteCond (or to a set of RewriteConds). Here is an example that applies one Cond to three Rules:

RewriteCond  %{HTTP_HOST}  !^www.mydomain.com$
# skip rules if NOT within domain - only way to tie multiple rules to one cond
RewriteRule  .?  -  [S=3]
RewriteRule  ^path1(/.*)$  /otherpath1$1
RewriteRule  ^path2(/.*)$  /otherpath2$1
RewriteRule  ^path3(/.*)$  /otherpath3$1

To change an existing Cond to work for multiple Rules you have to:

  • Negate the condition (prepend it with !)
  • If you have multiple RewriteConds:
    Change logical ANDs in the Conds to ORs and vice versa.
  • Add a skipping rewrite rule in front of all rules that you want to tie to the condition(s). Set the S parameter to the number of Rule lines to be skipped.

Please be aware that it is not possible to use any backreferences that point back to the RewriteCond (like %1) in the skipped Rules. These are only accessible in the skipping RewriteRule.