How to combine RewriteCond in htaccess - .htaccess

I am looking for If, else type of code which can combine my re-write rules based on host/domain name. So if domain name is "domainA" then redirect a to b, c to d and if domain name is "domainB" then redirect x to y and z to p. Basically I don't want to write the Condition again and again as I have done below:
I have written following code for htaccess
RewriteCond %{HTTP_HOST} ^domain\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^home /? [L,R=301]
RewriteCond %{HTTP_HOST} ^domain\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^home-old /? [L,R=301]
In above I am using host because I have multiple domains pointed to same hosting space so htaccess is common between all.
Can I combine the above multiple condition for a domain into one, instead of writing domai name again and again for some set of redirects for specific domain?
Please advise, thanks!

There really is no such if-then-else structure in mod_rewrite. You have to either be clever with your rules (which sometimes makes them unreadable or impossible to amend) or just be explicit about everything.
For your specific example, you can just use regular expressions to combine them:
^domain\.com$ and ^www\.domain\.com$ gets turned into ^(www\.)?domain\.com$
and
^home and ^home-old is just ^home, since the first only matches if the URI starts with home, and home-old does indeed start with home (there is no $ symbol to indicate the end of the string). So you're looking at:
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteRule ^home /? [L,R=301]
If you need to be specific by using the $, you can just change the regex to:
RewriteRule ^home(-old)?$ /? [L,R=301]
EDIT:
If I have some other urls instead of home, and botique, and hairtips then I need to write RewriteCond every time? I guess I have to write that every time just confirming from you
Yes, you have to repeat the condition every time, or, you can make a passthrough at the very beginning of your rules:
RewriteCond %{HTTP_HOST} !^(www\.)?domain\.com$ [NC]
RewriteRule ^ - [L]
This means: anything that's not a request for host: www.domain.com or domain.com, then pass through without rewriting. Then you can just have rules after this because only requests with hosts other than the above will reach those rules.
This is the "clever" bit that I was referring to before. This can make it tricky to change your rules or amend them later because you've set a strict condition at the top.

Related

.htaccess redirect domain without language subfolder to language subfolder

I had got a domain like this "domain.com", now I create subfolders for languages.
Now my domain has this subfolders "domain.it/it/" and "domain.com/en/".
I need to redirect only the root domain "domain.it" to "domain.com/it/, I tried to do this in my .htaccess but it goes in "Too many redirect":
RewriteCond %{HTTP_HOST} ^(www\.)?domain.it$ [NC]
RewriteRule ^(.*) https://www.domain.it/it/ [R=301,L]
And this:
RewriteCond %{REQUEST_URI} !^/(en|it)/
RewriteRule ^(.*)$ https://www.domain.it/it/ [L,R=301]
How can I do that?
Thanks
The first rule + condition always match so cause an infinite loop. You only need one rule for this situation:
RewriteRule ^(?!(?:it|en)/).* https://www.domain.it/it/$0 [L,R=301]
This uses a negative look-ahead assertion with non-capturing sub-pattern. However, I'd advise you also add another rule (before that one) to aid manually entered/poorly copied URLs:
RewriteRule ^(?:it|en)$ https://www.domain.it/$0/ [L,R=301]

Rewrite subdomain url to root domain url

I use the following rules to rewrite a subdomain call to a page in the root of the website:
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^([a-zA-Z0-9/_.-]+)\.domain\.com$ [NC]
RewriteRule .? headlines.php?url=%1 [L,QSA]
This works fine. I use this for a rss - news related website. For example: http://economy.headlines.com will internally look at http://www.headlines.com/headlines.php?url=economy
I also want to link to the news items in the following way:
economy.headlines.com/news/title/id
How do i do this ? Because every time the first rules are "fired". Even if i make other rules with the [L] flag the other rules are fired and nothing happened.
How can i combine the rules above with new rules which also look at files in the root of the site but with parameters in the url ?
You should be able to combine both if you evaluate the path component of the request you rewrite:
Rewriteengine on
RewriteCond %{HTTP_HOST} !^www.domain.com$ [NC]
RewriteCond %{HTTP_HOST} ^([a-zA-Z0-9/_.-]+).domain.com$ [NC]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ headlines.php?url=%1&category=$1&title=$2&id=$3 [L,QSA]
Probably you have to do some fine tuning, but I think you get the idea: the first argument of the RewriteRule is a regular expression that splits the request path into its components. Those can be referred to using the $1 and $2 notation you can see towards the end of the rule.
Edit: added the category parameter to the RewriteRule as discussed in the comments below.

redirect using htaccess from subdomain to domain (individual files)

I have a subdomain (store.example.com). Not only do I want to redirect traffic from store.example.com but I want to redirect it to specific files on the domain (everything I could find was based on redirecting the entire subdomain)
So I want store.example.com/Science-Fiction -> www.bundoranpress.com/category/1/Science-Fiction
How would I write this using htaccess file?
You will either need a couple of RewriteConds or (in my opinion the better approach) a php script handling your requests. For the first approach:
RewriteCond %{HTTP_HOST} ^([^\.]+)\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} ^(ThanksForAllTheFish) [NC]
RewriteRule (.*) http://www.bundoranpress.com/$1/$2 [L,R]
This will redirect store.example.com/ThanksForAllTheFish to www.bundoranpress.com/store/ThanksForAllTheFish selling Douglas Adam's books.
Now, you could go for adding all possible terms in the second RewriteCond like so:
RewriteCond %{REQUEST_URI} ^(ThanksForAllTheFish|Universe|Hitchhiking) [NC]
This would capture one of the terms and redirect to the corresponding address (e.g. www.bundoranpress.com/store/Universe). You see that this will be difficult very quickly.
A better approach would be to redirect all urls from a specific folder and subdomain to a php script handling the rest, like so:
RewriteCond %{HTTP_HOST} ^([^\.]+)\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} ^books/(.*) [NC]
RewriteRule (.*) http://www.bundoranpress.com/index.php?sub=$1&cat=$2 [L,R]
This would redirect store.example.com/books/ThanksForAllTheFish to www.bundoranpress.com/index.php?sub=store&cat=ThanksForAllTheFish. You could access the variables via $_GET["sub"] and $_GET["cat"] respectively. This gives you a much greater flexibility at hand.

Creating a mod_rewrite rule in an htaccess file

I am trying to create a mod_rewrite rule to direct people to a sub-folder. Currently the code looks as follows:
RewriteEngine On
RewriteCond %{HTTP_HOST} abcsite.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^!www\.abcsite\.*$
RewriteCond %{REQUEST_URI} !^/abc/.*$
RewriteRule (.*)$ /abc/$1 [L]
The redirect works if the user types www.abcsite.com, but not if they type abc.com. Is there something that I am missing or should do differently to make sure the user goes to the correct folder (regardless of how they type the URL)?
Side note: The htaccess file that I am dealing with is a Joomla file, so all contents of it deal with another Joomla site. I appreciate the help.
Because you have conditions for that.
RewriteCond %{HTTP_HOST} abcsite.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^!www\.abcsite\.*$
RewriteCond %{REQUEST_URI} !^/abc/.*$
All above rules will pass only its abcsite.com
You add following rules also then it work for abc.com too.
RewriteCond %{HTTP_HOST} abc.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^!www\.abc\.*$
RewriteCond %{REQUEST_URI} !^/abc/.*$
RewriteRule (.*)$ /abc/$1 [L]
There's a stray ! in your second condition. A ! in front of the pattern means that the condition is true when the regex doesn't match (like in the third condition). A ! inside the pattern is just a literal symbol.
The host conditions should be something like:
RewriteCond %{HTTP_HOST} ^abcsite\.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^www\.abcsite\.com$ [NC]
And in fact, they can be joined into a single condition (note, no [OR] here):
RewriteCond %{HTTP_HOST} ^(www\.)?abcsite\.com$ [NC]
Your third condition is intended to prevent redirect loops (/foo → /abc/foo → /abc/abc/foo → …). What it says is that the rule isn't applied if the request URL starts with /abc/. However, your actual redirect is an internal redirect: if a user accesses abcsite.com/foo, the server internally rewrites this to /webroot/abc/foo, but REQUEST_URI stays the same, /foo.
The reason this doesn't cause a redirect loop as it is is likely rewrite rules in abc/.htaccess which override this one once the redirect is done.
What should be checked instead in the third condition is the path matched by the rewrite rule:
RewriteCond $1 !^abc/
RewriteRule (.*) /abc/$1 [L]

how do i fix this rewrite URL rule?

basically need to convert
with www or not, example.com/[anycharacter]
into
with www or not, example.com/cgi-bin/new-disk.cgi/dir/smooth/[anycharacter]
additinoally...
i would like to redirect ALL www.example.com into example.com
This should work for you:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !cgi-bin/new-disk.cgi/dir/smooth
RewriteRule ^(.*)$ /cgi-bin/new-disk.cgi/dir/smooth/$1 [L]
For the first two lines, it checks to see if you have www in your URL. If so, bounce it to the non-www version.
Note the exclamation mark (!) on the second last line. This is a not operator and in this test, is checking to see if your currently requested file isn't your final rewriting file, in this case:
cgi-bin/new-disk.cgi/dir/smooth
If that's true, shunt it to the actual rewrite script you have as pointed out in the final line.
The character, $1, references the first capture group as marked by the first set of parentheses on the same line.
For part of your answer, I believe you can use this as an example to base off.. hopefully you use a test domain:
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^/(.*) http://example.com/$1 [L,R=301]
Might need to add a (.*) and make it optional for the other part.

Resources