Add slashes and redirect pages with htacess and apache - apache

Im trying to make it so everything with news.php in the url gets redirected to a url which strips out the news.php and adds a trailing slash. So http://www.example.com/news.php/news/article to http://www.example.com/news/article/
Ive been able to remove the news.php with this
RewriteRule ^(news|health|tips|weight|P[0-9]{2,8})$ $1/ [NC]
RewriteCond $1 ^((news|health|tips|weight|P[0-9]{2,8})/) [NC]
RewriteRule ^(.*)$ /news.php/$1 [L]
Ive tried adding a trailing slash to the above line and it does nothing.
I have also tried the stuff below, which adds a slash but doesnt remove the news.php.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /news.php/$1/ [R=301,L]
Can someone help me out here Im not sure what to do?
I also have some other rules
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{QUERY_STRING} ^(ACT=.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(URL=.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(CSS=.*)$ [NC]
RewriteRule ^$ /news.php\?&%{QUERY_STRING} [L]
RewriteRule ^(.*)$ $1.php [L,QSA]
RewriteCond %{HTTP_HOST} !^www2\.
RewriteRule ^(.*)$ http://www2.%{HTTP_HOST}/$1 [R=301,L]

You need an additional rule:
RewriteEngine On
RewriteCond %{THE_REQUEST} /news\.php/\S+ [NC]
RewriteRule ^news\.php/(.+?)/?$ /$1/? [R=301,L]
RewriteCond $1 ^((news|health|tips|weight|P[0-9]{2,8})/) [NC]
RewriteRule ^(.+)$ /news.php/$1 [L]
EDIT: To add a trailing slash to all non-files:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301]

Ok so I changed the first block anubhava suggested to
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
and now everything seems to be working as I want.

Related

How to resolve conflicting mod_rewrite rules and conditions

I have a couple of rewrite rules in my .htaccess that seem to be conflicting.
I am running an ExpressionEngine (CodeIgniter) website that resolves all URI's using an index.php file. I have removed the index.php from the URI's for aesthetic reasons.
What I am trying to achieve:
Redirect 301 all pages with a trailing slash (example.com/bla/ =>
example.com/bla)
Remove index.php from all URI's
What I have now:
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{SERVER_ADDR} !=127.0.0.1
RewriteCond %{SERVER_ADDR} !=::1
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond $1 !^(images|system|themes|index\.php|admin\.php|favicon\.ico|robots\.txt|humans\.txt|crossdomain\.xml) [NC]
RewriteRule ^(.*)$ index.php/$1 [L]
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
</IfModule>
What works:
All deeplinks are redirected to their non-trailing-slash version
(example.com/bla/ => example.com/bla).
index.php is removed from all deeplink pages.
What does not work:
The homepage (example.com) gives me an error in Google Chrome, saying "Too many redirects".
How do I update the conditions and rules so that I achieve clean links without a trailing slash, and without index.php, regardless of which page it is.
Have it like this:
RewriteCond %{HTTPS} !=on
RewriteCond %{SERVER_ADDR} !=127.0.0.1
RewriteCond %{SERVER_ADDR} !=::1
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule ^(.*?)index\.php(/.*)?$ /$1$2 [R=301,NE,L]
RewriteCond $1 !^(images|system|themes|index\.php|admin\.php|favicon\.ico|robots\.txt|humans\.txt|crossdomain\.xml) [NC]
RewriteRule ^(.*)$ index.php/$1 [L]
Clear your browser cache before testing.

Using htaccess to redirect all pages but one to another domain

My htaccess is as follows:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain\.es$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain\.es$
RewriteRule ^(.*)$ http://www.domain.com/es [L,R=301]
RewriteCond %{HTTP_HOST} !^www.domain.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?section=$1 [QSA,L]
Basically it's function is to redirect all domain alias (i.e. domain.mobi) to domain.com, except domain.es, that will be redirected to domain.com/es. Then there's another rewriterule that appends the query string (so in the background, domain.com/test becomes domain.com/index.php?section=test)
My problem is that now I need to exclude a url (www.domain.es/landing) from the redirection (so it stays in domain.es), and I can't make it work. I've tried adding this condition to the first two rules to exclude the page:
RewriteCond %{REQUEST_URI} !^/landing$
but then it goes to www.domain.com/es?section=landing (not only still redirects to domain.com; the query string appears in the browser bar). Any ideas?
You can use these rules:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.es$ [NC]
RewriteCond %{THE_REQUEST} !/landing[\s?] [NC]
RewriteRule ^(.*)$ http://www.domain.com/es/$1 [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{THE_REQUEST} !/landing[\s?] [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?section=$1 [QSA,L]

Redirect to new url except for on page with existing expression engine redirect

I have the following redirects in the .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_URI} /content [NC]
RewriteRule (.*) http://subdomain.domain1.co.uk/index.php/$1 [R=301,L]
RewriteCond %{REQUEST_URI} !^/content$ [NC]
RewriteRule (.*) http://www.domain2.co.uk/$1 [R=301,L]
The first redierect needs to be there for the expression engine to work properly. Visit to
subdomain.domain1.co.uk/content matches the rule but I end up in the indefinite redirect loop. Can anybody help ?
Thanks,
EDIT: 2nd and 3rd rule may actually be incorrect. What I want it to do is to redirect anything from http://subdomain.domain1.co.uk/$1 to http://www.domain2.co.uk/$1 expect for http://subdomain.domain1.co.uk/content and http://subdomain.domain1.co.uk/content/*
Keep your rules like this:
RewriteEngine on
# redirect everything except content/? to www.domain2.co.uk
RewriteCond %{HTTP_HOST} ^(www\.)?subdomain\.domain1\.co\.uk$ [NC]
RewriteCond %{THE_REQUEST} !\s/content/?[\s?] [NC]
RewriteRule ^ http://www.domain2.co.uk%{REQUEST_URI} [R=301,L,NE,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L,QSA]

URL RewriteRule in .htaccess for index.php query parameters

Example URL's:-
www.domain.com/index.php?bob
www.domain.com/index.php?jane
www.domain.com/index.php?fred
Need rewriting like:-
www.domain.com/bob
www.domain.com/jane
www.domain.com/fred
Have tried with many variations now but the closest I can get to is:-
www.domain.com/?bob
www.domain.com/?jane
www.domain.com/?fred
The below in .htaccess achieves this...
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]
Please could someone point out what I need to modify to bin the ? (question mark) in the URL?
Edit
Just noticed that since applying the answer given by anubhava below that robots.txt for example doesn't resolve to the .txt file but just displays the homepage.
.htaccess below:-
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/+index\.php\?([^\s&]+) [NC]
RewriteRule ^ %1? [R=301,L]
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#pos1
RewriteRule ^([^/]+)/?$ index.php?$1 [L,QSA] <--
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
#pos2
If I add the <-- line in pos1, the robots.txt URL returns a 404 page not found error.
If I add the <-- line in pos2, the robots.txt URL just displays the homepage.
Edit2
In the meantime, I have excluded robots.txt from rewrites by adding the following under Rewrite Base /:-
RewriteRule ^robots.txt - [L]
You can use this code:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/+index\.php\?([^\s&]+) [NC]
RewriteRule ^ %1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?$1 [L,QSA]
You can also use this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]

combination of rewrite rules not working

RewriteEngine On
RewriteCond %{HTTP_HOST} !.com$ //redirect from .net and .org to .com
RewriteRule .* http://www.domain.com%{REQUEST_URI} [R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC] //Always use www.
RewriteRule ^/(.*)$ http://www.%1/$1 [R=301]
RewriteRule ^/?article-(.*)$ article.php?id=$1 [L,QSA,NC] // redirect article-x to article.php?id=x
RewriteRule ^/?page-(.*)$ page?p=$1 [L,QSA,NC]// redirect page-x to page.php?p=x
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L] // add the .php to every request if the file type is missing
all the rules work fine except for adding www. to url. for example http://domain.com/page-1
doesn't get redirected to http://www.domain.com/page-1
%1 refers to a pattern captured with () in the preceding RewriteCond. You haven't captured any patterns in RewriteCond. Instead, you can just use %{HTTP_HOST} in the RewriteRule.
If these rules reside in .htaccess, RewriteRule will not contain a leading /, and will therefore never match if your pattern does. Remove the / and match on ^(.*)$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301]
Side note: don't forget to escape the . in .com. It will work unescaped, but the expression doesn't mean what you literally intend it to mean.
RewriteCond %{HTTP_HOST} !\.com$
The full set of rewrites all together should look like the following (I have removed all the leading / and /? expressions). I have tested all of this as working on my own system.
RewriteEngine On
RewriteCond %{HTTP_HOST} !\.com$ [NC]
#Use a capture group here, add [L]
RewriteRule (.*) http://www.example.com/$1 [L,R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
RewriteRule ^article-(.*)$ article.php?id=$1 [L,QSA,NC]
RewriteRule ^page-(.*)$ page?p=$1 [L,QSA,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]