Going mad with infinite loop and RewriteCond, need help - .htaccess

I want to redirect users to my home page if they enter any URL not starting with 'en' or 'fr'. I've spent hours trying to make this work but this proves too tough for my fragile newbie brain. Currently, if I try to go to
http://mysite.com/fr/produits/
Firefox tells me that the redirect will never complete.
Here's what I want:
http://mysite.com/en/whatever/ ==> rewrite as /whatever/index.php?lang=en
http://mysite.com/fr/whatever/ ==> rewrite as /whatever/index.php?lang=fr
http://mysite.com/jp/whatever/ ==> 301 redirect to /fr/accueil/
http://mysite.com/whatever/ ==> 301 redirect to /fr/accueil/
Here's my current htaccess. See inline comments for details.
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Require no www
RewriteCond %{HTTP_HOST} !^mysite\.com$ [NC]
RewriteRule ^(.*)$ http://mysite.com/$1 [R=301]
# Redirect from root to /fr/accueil/, the URL for the default home page
RewriteRule ^/$ http://mysite.com/fr/accueil/ [NC,R=302]
# Rewrite language path fragment (/fr or /en) as a parameter
RewriteRule ^fr/accueil/$ /accueil/index.php?lang=fr [QSA,NC]
RewriteRule ^en/home/$ /accueil/index.php?lang=en [QSA,NC]
RewriteRule ^fr/produits/$ /produits/index.php?lang=fr [QSA,NC]
RewriteRule ^en/products/$ /produits/index.php?lang=en [QSA,NC]
# I'm aware that the rules in this htaccess are re-examined each
# time a rewrite is issued. So the 'fr/accueil/' I'm redirecting to
# will itself be rewritten as /accueil/index.php?lang=fr. That is
# why I'm providing 3 conditions:
# If URI does not start with 'en' AND
# If URI does not start with 'fr' AND
# If QUERY_STRING is not exactly 'lang'
RewriteCond %{REQUEST_URI} !^en/.*$
RewriteCond %{REQUEST_URI} !^fr/.*$
RewriteCond %{QUERY_STRING} !^lang$
RewriteRule ^.*$ fr/accueil/ [NC,R=301]
Please put me out of my misery. Cheers!

try replacing the last line
RewriteRule ^.*$ fr/accueil/ [NC,R=301]
With
RewriteRule ^.*$ fr/accueil/ [NCL,R=301]

Related

php - Htaccess as fake directories

I am making a mini blog that could make it's url looks like this:
From: http://127.0.0.1/index.php?post=the-story-of-us
To: http://127.0.0.1/view/the-story-of-us
I have tried this but i'm getting 404 not found.
RewriteEngine on
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /index\.php\?post=([^&]+)
RewriteRule ^ /view/%2/? [L,R=301]
Your current rule only handles the case: Redirect old url to new url.
(By the way, +1 for using THE_REQUEST to avoid a redirect loop)
You also need to handle the case: Rewrite (internally) new url to old url.
Here is how your htaccess should look like
RewriteEngine On
# Redirect /index.php?post=XXX to /view/XXX
RewriteCond %{THE_REQUEST} \s/index\.php\?post=([^&\s]+)\s [NC]
RewriteRule ^ /view/%1? [L,R=301]
# Internally rewrite back /view/XXX to /index.php?post=XXX
RewriteRule ^view/([^/]+)$ /index.php?post=$1 [L]
I do not udnerstand your RewriteCondition, but the RewriteRule should look like this:
RewriteEngine on
RewriteBase /
RewriteRule ^view/(.*)/? ./index.php?post=$1 [L,R=301]

Implementing "friendly" URLs using .htaccess

I tried some of the other answers I could find in here, but it didn't work out. It's really simple though.
I want
/page?id=PAGENAME
to be accessible AND redirected to
/PAGENAME
Can you help me?
EDIT:
It feels like my already messed-up .htaccess file needs to be included in here. I already have basic rewriting enabled, but this feature is needed for two other "special pages". In the requested solution above, I would therefore just replace "page" with the two pagenames (it's danish names, so I thought it was easier this way).
Currently I have this. If you have any improvements to it, it's appreciated - but I just want this to work with the requested solution aswell.
# Options -Multiviews -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
# Always on https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# remove trailing slash
#RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]
#301 Redirect everything .php to non php
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^.]+\.)+php?\ HTTP
RewriteRule (.+)\.php?$ http://MYURL.dk/$1 [R=301,L]
#Hide the .php from url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
#301 Redirect everything mistype after file extension -
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
#301 Redirect everything to current url -
RedirectMatch permanent /(.*).php/.* http://MYURL.dk/$1.php
RewriteCond %{REQUEST_FILENAME} -D
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L]
#301 Redirect from non www to www
RewriteCond %{HTTP_HOST} ^www.MYURL.dk [NC]
RewriteRule (.*) http://MYURL.dk/$1 [R=301,L]
#301 redirect index.php to /
RewriteBase /
RewriteCond %{REQUEST_URI} index.php
RewriteRule .* http://MYURL.dk/ [R=301,L]
#Deny access to songs
RewriteCond $1 !(loadmedia)\.php
RewriteRule ^songs/(.*)$ - [L,F]
Generally the URL in address bar should be like
www.siteurl.com/pagename/ for seo purpose and then read this url from .htaccess using rule which gives this query string parameter values in your php file.
.htaccess rule can be like
RewriteRule ^(.*)/$ /page?id=$1 [QSA,L]
It looks like you are wanting to implement "friendly" (or "pretty") URLs, making the URLs more friendly for you users (search engines don't really mind what your URLs look like).
The first step is to change all your on-page links to use the new "friendly" URL. So, you links should all be of the form /pagename (not /page?id=PAGENAME).
Then, in .htaccess, you need to internally rewrite this "friendly" URL into the real URL that your server understands. This can be done using mod_rewrite. In the .htaccess file in your document root:
# Enable the rewrite engine
Options +FollowSymLinks
RewriteEngine On
# Rewrite the "friendly" URL back to the real URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !^id=
RewriteRule ^([\w-]*) /page?id=$1 [L]
If the file does not exist (!-f) and does not contain the id URL param then internally rewrite the request from /<pagename> to /page?id=<pagename>. This assumes your <pagename> consists only of the characters a-z, A-Z, 0-9, _ and -.
If this is a new site and the old URLs are not already indexed or referenced by external sites then you can stop here.
However, if you are changing an existing URL structure then you also need to externally redirect the real (ugly) URL to the "friendly" URL before the above internal rewrite. (This is actually what you are asking in your question.) In order to prevent a rewrite loop we can check against %{THE_REQUEST} (which does not change when the URL is rewritten).
# Redirect real URLs to "friendly" URLs
RewriteCond %{THE_REQUEST} \?id=([\w-]*)
RewriteRule ^page$ /%1? [R=302,L]
Change the 302 (temporary) to 301 (permanent) when you are sure this is working OK. Permanent redirects are cached by the browser so can make testing a problem.
So, in summary, with the above two parts shown together:
# Enable the rewrite engine
Options +FollowSymLinks
RewriteEngine On
# Redirect real URLs to "friendly" URLs
RewriteCond %{THE_REQUEST} \?id=([\w-]*)
RewriteRule ^page$ /%1? [R=302,L]
# Rewrite the "friendly" URL back to the real URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !^id=
RewriteRule ([\w-]*) /page?id=$1 [L]
The order of directives is important. External redirects should nearly always come before internal rewrites.
UPDATE#1:
I want /concept?id=NAME to go to /NAME and /studio?id=NAME to go to /NAME - there's 5-10 different "pages" from both concept and studio. [Corrected according to later comment]
Since id=NAME maps to /NAME you can achieve all 10-20 redirects with just a single rule:
RewriteCond %{QUERY_STRING} ^id=(NAME|foo|bar|baz|abc|def|ghi)
RewriteRule ^(concept|studio)$ /%1? [R,L]
This will redirect a URL such as /studio?id=foo to /foo.
As with all external redirects this should be one of the first rules in your .htaccess file.
Change R to R=301 when you have tested that it is working OK.
To make this more "dynamic", ie. match any "NAME" then change the CondPattern, for example:
RewriteCond %{QUERY_STRING} ^id=([\w-]*)
UPDATE#2:
If the path part of the URL (ie. concept or studio) is required then you can modify the RewriteRule substitution like so:
RewriteCond %{QUERY_STRING} ^id=([\w-]*)
RewriteRule ^(concept|studio)$ /$1/%1? [R,L]
Which will redirect /concept?id=foo to /concept/foo.
Or, to be completely "dynamic" (bearing in mind this will now capture anything):
RewriteCond %{QUERY_STRING} ^id=([\w-]*)
RewriteRule ^([\w-]+)$ /$1/%1? [R,L]

301 Redirect - variable in the old url

I have several urls on a Joomla site which have been indexed and I need to 301 redirect them into some new pages. The old URL is formed like this:
http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=20
I want it to go to:
http://www.mydomain.com/en/family-members/family-disease
I tried using:
RewriteCond %{QUERY_STRING} ^start=(.*)$
RewriteRule ^/en/wfmenuconfig/family/family-disease/177-category-english$ http://www.www.mydoamin.com/en/family-members/family-disease%1 [R=301,L]
I've tried several answers on here but nothing seems to be working.
htaccess 301 redirect dynamic url
and
301 Redirecting URLs based on GET variables in .htaccess
Any ideas what I should try next? (I've tried a normal redirect 301)
You've almost got it. You need to remove the leading slash from your rule's pattern because it's removed from the URI when applying rules from an htaccess file:
RewriteCond %{QUERY_STRING} ^start=(.*)$
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english$ /en/family-members/family-disease%1? [R=301,L]
You also don't need the http://www.www.mydoamin.com bit (2 sets of www). At the end of your target, you have family-disease%1, which means if start=20 then the end of your URL will look like: family-disease20. Is that right?
The new URL doesn't have the query string in it, so it is just stripping of the last URL path part. If you want it hardcoded
RewriteCond %{QUERY_STRING} ^start=
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english$ /en/family-members/family-disease? [R,L]
or a little bit more flexible
RewriteCond %{QUERY_STRING} ^start=
RewriteRule ^en/wfmenuconfig/family/family-disease/.+$ /en/family-members/family-disease? [R,L]
or if you just want to keep two levels after en/wfmenuconfig
RewriteCond %{QUERY_STRING} ^start=
RewriteRule ^en/wfmenuconfig/(.+?/.+?)/ /en/$1? [R,L]
Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.
If you just want to redirect http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=$var into http://www.mydomain.com/en/family-members/family-disease, then you must try these directives:
# once per .htaccess file
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{QUERY_STRING} start=([0-9]*)
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english /en/family-members/family-disease [R=301,L]
But if that's not what you want, but to redirect http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=$var into http://www.mydomain.com/en/family-members/family-disease$var then you could check this one:
# once per .htaccess file
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{QUERY_STRING} start=([0-9]*)
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english /en/family-members/family-disease%1 [R=301,L]
Now, give this one a little more try if it will work. If it's not, then find any suspicious why this code is not working:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /en/
RewriteCond %{QUERY_STRING} start=([0-9]*)
RewriteRule ^wfmenuconfig/family/family-disease/177-category-english /family-members/family-disease [R]
And go to http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=$AnyNumber if it's redirecting into http://www.mydomain.com/en/family-members/family-disease just make sure that your web server have mod_rewrite.
I just wanted to throw this out there, I was also having trouble getting the RewriteRule to work. I have a client that upgraded to a WordPress powered site from .asp pages. What I had to do to get this to work is insert the RewriteCond and RewriteRule in the htaccess file BEFORE the "# BEGIN WordPress" section. Now it works just as it should.
This is posted way late, but hopefully it helps someone else out there running into the same issue.
Doesn't Work:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
RewriteCond %{QUERY_STRING} ^var=somestring$ [NC]
RewriteRule ^oldpage\.asp$ http://www.domain.com/newpage? [R=301,L]
Does Work:
RewriteCond %{QUERY_STRING} ^var=somestring$ [NC]
RewriteRule ^oldpage\.asp$ http://www.domain.com/newpage? [R=301,L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Order of operations must be important =)

htaccess rewrite still some problems, getting a bit complex eek!

Another edition to my .htaccess rewriting saga. Everything is now working to a degree but still have some issues.
I have numerous rules to move old urls to new urls, passing variables etc - however there are still a couple of things i need to add, and for the life of me cannot figure out.
I have 3 urls that are directing/rewriting as below.
1 www.mydomain.com/news/dentistry_dental/index.php
2 www.mydomain.com/news/dentistry_dental/index.php?month=April&year=2011
3 www.mydomain.com/news/dentistry_dental/article_detail.php?article=1234&title=some-title
These are redirected & rewritten perfectly to the new urls respectively
1 www.mydomain.com/dental_news/
2 www.mydomain.com/dental_news/April-2011
3 www.mydomain.com/dental_news/1234-some-title
However... Here is the problem #1 The following urls are also redirecting as below
4 www.mydomain.com/news/it_technology/index.php?month=April&year=2011
5 www.mydomain.com/news/it_technology/article_detail.php?article=1234&title=some-title
Which are also directing to the same urls as the dental redirects
4 www.mydomain.com/dental_news/April-2011
5 www.mydomain.com/dental_news/1234-some-title
Which shouldnt be happening. The it_technology news articles have now been removed so i wish to redirect them either to my homepage with a 410 or something similar, whichever is the best option really.
My current .htaccess looks as follows.
Options +FollowSymlinks
RewriteEngine on
rewritecond %{http_host} ^mydomain.com [nc]
rewriterule ^(.*)$ http://www.mydomain.com/$1 [r=301,nc]
# Rewrite all index.php to root: / ( with perm redirect )
RewriteCond %{REQUEST_URI} !/generator/
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.mydomain.com/$1 [R=301]
RewriteRule ^products/dental-digital-imaging/([^/]*)_([^/]*)$ /products/digital_xray.php?id=$1&product=$2 [L]
RewriteRule ^products/package_deals.php$ http://www.mydomain.com/products/dental-computer-network-bundles [R=301]
RewriteRule ^products/computer_hardware.php$ http://www.mydomain.com/products/dental-computer-solutions [R=301]
RewriteRule ^products/individual_computers.php$ http://www.mydomain.com/products/dental-computer-systems [R=301]
RewriteRule ^products/digital_xray_imaging.php$ http://www.mydomain.com/products/dental-digital-imaging [R=301]
RewriteRule dental_news/$ /news/dentistry_dental/?rewrite [L]
# Rewrite dental news article to neat nice url
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule ^dental_news/([0-9]*)-([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&rewrite [L]
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [L,R=301]
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [R=301]
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule news/dentistry_dental/$ /dental_news/ [R=301]
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule ^dental_news/([a-zA-Z]*)-([0-9]*)/?$ news/dentistry_dental/index.php?month=$1&year=$2&rewrite [L]
# Rewrite URL stripping .php Extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
My only other requirement would be to add a trailing slash to the php files served ( that have allready add the .php extension removed with the last rule in my .htaccess.
I have tried numerous ways that i have found via google, but all of them cuase probelms with my other rules.
Hopefully someone can help me finish this off once and for all.
Regards
M
Sure is getting complicated :) Try changing these lines (I think there are 2):
RewriteCond %{REQUEST_URI} !^/dental_news/
to:
RewriteCond %{REQUEST_URI} ^/news/dentistry_dental/
That way its only going to redirect the old dental news URLs to there respective new ones.
Trivially, your problem is the catch-all rules:
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [L,R=301]
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [R=301]
Restrict them to the path you want to rewrite, i.e. replace .* with something more specific, like:
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule ^news/dentistry_dental/index.php$ /dental_news/%1-%2? [L,R=301]
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)$
RewriteRule ^news/dentistry_dental/index.php$ /dental_news/%1-%2? [R=301]
You can do the news/it_technology redirect as a standard redirect.
RewriteRule ^news/it_technology http://www.thepage.com/ [R=301,L]
It might technically be more correct to do a 410, but the 410 code is really optional. You might also want to make it 404, and then have a link from the 404 page to the main page.

How to set htaccess to redirect/rewrite from to subdomain

I want htp://www.seostuff.org.ua/?s=seo to be redirected to htp://seo.seostuff.org.ua
Instead of seo can be any other search pattern
Buy this way I managed to make htp://seo.seostuff.org.ua redirecting to htp://www.seostuff.org.ua/?s=seo
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.seostuff\.org\.ua
RewriteCond %{HTTP_HOST} ^(.*)\.seostuff\.org\.ua [NC]
RewriteRule .* http://www.seostuff\.org\.ua/?s=%1 [L]
But I do not want URL change it should stay the same, ex htp://seo.seostuff.org.ua
I want revert requests to be processed as well (means htp://www.seostuff.org.ua/?s=seo should 301 redirect to htp://seo.seostuff.org.ua)
Also I do not need any slowness of processing such URL requests. Want to create optimized Rules. Any help please?
I would really appreciate this.
You cannot rewrite to a full HTTP URL without redirect to it.
So try this:
RewriteEngine on
# rewrite abc.seostuff.org.ua to abc.seostuff.org.ua/?s=abc
RewriteCond %{HTTP_HOST} !^www.seostuff.org.ua
RewriteCond %{HTTP_HOST} ^(.*).seostuff.org.ua
RewriteRule .* ?s=%1 [L]
# redirect seostuff.org.ua/?s=abc to abc.seostuff.org.ua
RewriteCond %{QUERY_STRING} ^s=([a-zA-Z0-9\-_]+)$
RewriteRule .* http://%1.seostuff.org.ua/ [L,R=301]

Resources