A few alternatives to using <If> sections, since <If> is not without its caveats.
- Skip directives when the condition does (or does not) match
- Prefix the URL (to match) with the hostname
- Separate
.htaccess config file for each host
(Aside: Do you really want a case-insensitive - NC - match?)
1. Skip directives when the condition does (or does not) match
You can skip (S flag) any number of directives when the rule (or condition) does not match. ie. If you skip the rules that follow when the HTTP_HOST is not domain1.com then the following rules are only processed when the HTTP_HOST is domain1.com.
For example:
# Skip the following 4 rules when the host is not "domain1.com"
RewriteCond %{HTTP_HOST} !=domain1.com
RewriteRule ^ - [S=4]
# Only processed when the HTTP_HOST is equal to "domain1.com"
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# Skip the following 5 rules when the host is not "domain2.com"
RewriteCond %{HTTP_HOST} !=domain2.com
RewriteRule ^ - [S=5]
# Only processed when the HTTP_HOST is equal to "domain2.com"
#main pages
RewriteRule ^about/$ /index.php?pageid=2 [NC,L]
RewriteRule ^press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=4 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
Although an obvious caveat with this approach is that you need to be careful to update the S=<number> flag when adding or removing any rules.
You can obviously reverse the logic to have what looks like a table-of-contents at the top. For example:
RewriteCond %{HTTP_HOST} =domain1.com
RewriteRule ^ - [S=2]
RewriteCond %{HTTP_HOST} =domain2.com
RewriteRule ^ - [S=5]
RewriteCond %{HTTP_HOST} =domain3.com
RewriteRule ^ - [S=9]
# --------------------------------------------------------------------
# domain1.com
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# domain2.com
#main pages
RewriteRule ^about/$ /index.php?pageid=2 [NC,L]
RewriteRule ^press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=4 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
Although the "skip" rules are potentially more prone to error since you may need to update several when adding or removing rules, depending on where these rules fall.
2. Prefix the URL (to match) with the hostname
Alternatively, you could (temporarily) prefix the URL-path with the hostname and match against this in the rules that follow. This avoids the additional RewriteCond directive in all subsequent rules.
For example:
# Prefix URL-path with HTTP_HOST if not already prefixed / No "L" flag
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1
# --------------------------------------------------------------------
# domain1.com
#main pages
RewriteRule ^domain1\.com/members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^domain1\.com/contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^domain1\.com/affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^domain1\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# domain2.com
#main pages
RewriteRule ^domain2\.com/about/$ /index.php?pageid=2 [NC,L]
RewriteRule ^domain2\.com/press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^domain2\.com/contact/$ /index.php?pageid=4 [NC,L]
RewriteRule ^domain2\.com/affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^domain2\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
This avoids the additional RewriteCond directive, however, it requires that you prefix the matched URL-path with the domain in each case. Less chance of error than with the use of the S flag as in the first example above.
In the above example, the hostname remains prefixed to the URL-path at the end of the request for any URL that does not map directly to a file or is not rewritten to /index.php?pageid=<number>. This would then result in a 404.
If you specifically wanted to remove the hostname prefix (perhaps you are using the $_SERVER['REDIRECT_URL'] variable in your error documents, as opposed to $_SERVER['REQUEST_URI']) then you could do this by introducing an additional environment variable (let's call it FINISHED) and remove this prefix at the end.
For example, modify the first rule to check the FINISHED env var (does not exist initially) and introduce a new rule at the end that removes the prefix and sets the env var. Without the FINISHED env var we'll get stuck in a rewrite loop for "unknown URLs" as it will repeatedly prefix and remove the hostname on the URL-path.
# Prefix URL-path with HTTP_HOST if not already prefixed and not FINISHED / No "L" flag
RewriteCond %{ENV:FINISHED} ^$
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1
# :
# : Directives for each domain go here (as above)
# :
# Tidy up - remove the HTTP_HOST prefix and set FINISHED env var
RewriteCond %{HTTP_HOST}@$1 ^([a-z.-]+)@\1/(.*)
RewriteRule (.*) %2 [E=FINISHED:1,L]
3. Separate .htaccess config file for each host
Another alternative that is perhaps more suited to this particular situation of separate domains and essentially separate websites (although perhaps a "common" engine) is to have additional (separate) .htaccess files for each site.
Exactly how you configure this could depend on exactly how you've configured your file structure, however, this enables an increased separation between your sites and to even share configs between two or more sites if you wish. You could have resources that relate just to the site being accessed - but you may have something like this already.
For example...
- You would still have the "master"
.htaccess file in the document root (assuming you share a common root directory for all domains).
- Create a subdirectory for each host. eg.
/domain1.com and inside each subdirectory you just have a .htaccess file for that domain.
File structure:
/
domain1.com/
.htaccess
domain2.com/
.htaccess
.htaccess
index.php
/.htaccess
The root .htaccess file would then route the request to the appropriate subdirectory for the requested host.
RewriteEngine On
# If the request is already for index.php in the document root then DONE
RewriteRule ^index\.php$ - [L]
# Rewrite all requests that don't map to files to the appropriate domain subdirectory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1 [L]
/domain1.com/.htaccess
Then each domain's .htaccess file contains just the directives for that domain and rewrites the request back to the "common" /index.php file in the document root to render the request.
The rewrite directives take the same "normal" format as used above.
# domain1.com
RewriteEngine On
# Optional - If this subdirectory is accessed directly then redirect back to the root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L]
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
Anyway, food for thought. Some of this comes down to how you structure your application rather than strictly "Grouping RewriteRule by RewriteCond". If you'd like further explanation of any "bit" then just say.