I think I have read everything I can about htaccess rewrites and I still can't make heads or tails of whats going on. I re made a website for work and all is well except the last designer did some crazy php stuff and all the urls he used have ?=p(pagename) I want to rewite those to (pagename).php then redirect them to with a 301 I am able to get the 301 redirects works just can't figure out how to rewrite the ?p=(pagename) to (pagename).php
You want to be matching against the actual requests, then internally rewrite it back to the query string:
RewriteEngine On
# 301 redirect to php file
RewriteCond %{THE_REQUEST} \ /\?p=([^&\ ]+)&?([^\ ]*)
RewriteRule ^ /%1.php?%2 [L,R=301]
# internally rewrite to the query string
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.php$ /?p=$1 [L,QSA]
You need to check the QUERY_STRING and then apply the rewrite rule
RewriteCond %{QUERY_STRING} ^p=(.*)$
RewriteRule ^(.*)$ http://mydomain.com/%1.php [R=301,L]
the ^p=(.*)$ checks for a query string that only has the one variable p=pagename, you will have to modify it if there will be any other variables in the query string it like p=pagename&id=15 etc
Related
I have the following URL
https://example.com/expert-profile?id=john-doe&locale=en
I want it to be redirected to
https://example.com/expert/john-doe
I tried the following
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]
And a couple of other solutions, nothing is working here. Can someone help me to go in the right direction?
Update:
This is my current .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
</IfModule>
Redirect 301 "/en/download-app" "/download-app"
Please keep your htaccess file in your root and have it in following way.
Please clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]
OR in case you don't have Rules to handle non-existing files/directories then use following Rules set. Please make sure either use above OR following Rules set one at a time only.
RewriteEngine ON
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(?:expert)/([^-]*)-(.*)$ $1-profile?id=$1&locale=$2 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ /index.html [L]
I have following URL
https://example.com/expert-profile?id=john-doe&locale=en
I want it to be redirected to
https://example.com/expert/john-doe
You would need to do something like the following at the top of your .htaccess file, before your existing directives (order is important):
RewriteCond %{QUERY_STRING} (?:^|&)id=([^&]+)
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]
This captures the value of the id URL parameter (in the %1 backreference) regardless of where it appears in the query string and discards all other URL parameters. I'm assuming you don't specifically need to match locale=en?
Note that the regex subpattern ([^&]+) (the id value) only matches something, not nothing. If the URL parameter is empty (ie. id=&locale=en) then no redirect occurs.
The QSD flag is necessary to discard the original query string.
Test first with a 302 (temporary) redirect to avoid potential caching issues. And clear your browser cache before testing. Only use a 301 (permanent) redirect if this really is intended to be permanent.
To redirect the specific URL /expert-profile?id=<name>&locale=en to /expert/<name>, ie. the id parameter is at the start of the query string and is followed by locale=en only then you can (and should) be more specific in the condition. For example:
RewriteCond %{QUERY_STRING} ^id=([^&]+)&locale=en$
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]
This is close (providing you placed the rule at the top of the file), however, this tries to preserve the other URL parameters, ie. locale=en and whatever else, to create another query string - which you've not stated in your requirements.
Aside: The existing answers are assuming you are wanting to internally rewrite (URL rewrite) the request in the other direction, ie. from /expert/john-doe to /expert-profile?id=john-doe&locale=en. This is probably due to how questions of this nature are notoriously miswritten and this is often the real underlying intention. However, you've made no mention of this here and a URL of the form /expert-profile is not a valid endpoint - so it wouldn't really make sense to "rewrite" the URL in that direction. (?)
If you want it rewritten, capture the name (.+) and insert it into the target $1
RewriteRule ^expert/(.+)$ /expert-profile?id=$1&locale=en [L]
And don't use flag R|redirect here, unless you really want a redirect.---
To redirect from expert-profile?id=john-doe to expert/john-doe, capture the id (.+?) from the query string and insert it in the substitution URL %1
RewriteCond &%{QUERY_STRING}& &id=(.+?)&
RewriteRule ^expert-profile$ /expert/%1 [R,L]
When everything works as it should, you may replace R with R=301 (permanent redirect).
Don't use both rules together. If you do, it will result in an endless redirect loop and finally give a "500 Internal Server Error".
Unrelated, but never test with R=301!
I would like to remove part of the url of my Joomla site and redirect to another url for example
www.example.com/xxx/yyy/zzz/FAQ
www.example.com/123/456/FAQ
to
www.example.com/FAQ
I'm very new to mod_rewrite in .htacesss
what RewriteRule can I write to achive this
thank you
Try this in root/htaccess
RewriteEngine On
RewriteCond %{THE_REQUEST} /xx/yy/zz/([^\s]+) [NC]
RewriteRule ^ /%1? [NC,L,R]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /xx/yy/zz/$1 [NC,L]
And the same rule can be used to rewrite /123/456/faq to /123/456/FAq , just change the rewrite target and the pattern in first Rewritecond.
$1 is part of the regex in rewrite rule, its the part matched between (.+) ,it contains uri.
Thank you, after I tried I finally got it working
this is my solution
RewriteEngine On
RewriteRule ^.*/FAQ$ /FAQ [L,R=301]
by doing this I remove everything between the URL and FAQ
www.abc.com/SOMETHING/SOMETHING2/FAQ
and redirect the URL to
www.abc.com/FAQ
I also found a nice tool to test the mod_rewrite code
http://htaccess.madewithlove.be/
I'm not sure if it is possible but I want rewrite old URLs to new style and if someone will access the old URL i want to 301 redirect him to new URL style
OLD URL: /catalogue/category/some-category-page
NEW URL: /some-category-page/category
Also what I need is to pass REQUEST_URI to PHP script
I've got something like this but its not working (recursion):
RewriteEngine On
RewriteRule ^catalogue/category/(.+)$ /$1/category [R=301,L] # this is bad I know
RewriteRule ^(.+)/category?$ /catalogue/category/$1 [P]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz)$ index.php?modrewrited=%{REQUEST_URI} [QSA,L]
Thank you for help.
If your PHP script needs to read from $_SERVER['REQUEST_URI'], the you need to make sure mod_proxy is loaded. Except that causes a redirect loop. You need to have your first rule which redirects check the actual request variable. So instead of:
RewriteRule ^catalogue/category/(.+)$ /$1/category [R=301,L] # this is bad I know
you want:
RewriteCond %{THE_REQUEST} \ /+catalogue/category/([^\ \?]+)
RewriteRule ^ /%1/category [L,R=301]
I'm using magento and every url is acessible in two ways for example:
http://www.mysite.com/product-item, and
www.mysite.com/product-item?___store=default
I tried a regular 301 redirect in .htaccess but it won't redirect. Does anyone have the code that would automatically redirect all url's with the suffix ?___store=default back to the clean url's thus avoiding duplicate content issues?
Try:
RewriteEngine On
RewriteCond %{THE_REQUEST} \?___store=default
RewriteRule ^(.*)$ /$1? [L,R=301]
or
RewriteEngine On
RewriteCond %{QUERY_STRING} ___store=default
RewriteRule ^(.*)$ /$1? [L,R=301]
depending on how the query string is generated. The reason why a Redirect 301 probably didn't work is that you can't match against query strings using that statement.
This is my current .htaccess file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/
RewriteRule ^([^/]+)/$ index.php?p1=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3&p4=$4 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3&p4=$4&p5=$5 [L]
Basically, it takes up to five "Friendly url folders" and assign the value to varibles and then, send those to my index.php page
IE: http://www.example.com/ford/focus/grey/
$p1 = 'ford';
$p2 = 'focus';
$p3 = 'grey';
$p3 = 'grey';
So far, so good.
Now, I need to integrate a 301 instruction (RegExp?) in that same .htaccess because initially, I had GET parameters like this :
IE: http://www.example.com/ford/focus/grey/?lang=fr
I need to get rid of all GET variables because Google sees it as duplicate content (even if I'm using the nofollow attribute on my languages links)
IE: http://i.want.to.keep/my/url/?AND_DUMP_GET_VARIABLES
http://www.example.com/ford/focus/grey/?lang=fr
http://www.example.com/ford/focus/grey/?lang=en
http://www.example.com/ford/focus/grey/?lang=sp
==> http://www.example.com/ford/focus/grey/
Logically, the instruction should be interpreted between the first and the second block but I just don't know where to start. Any hints?
THANKS!
As I understand you want to get rid of the QUERY STRING and redirect (301 Permanent Redirect) to the same URL but without QUERY STRING.
The rule below will redirect EVERY request that has query string:
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1? [R=301,L]
1. The ? will do the magic -- will strip query string
2. You desperately need this line: RewriteCond %{ENV:REDIRECT_STATUS} ^$. The problem is that it may not work on your Apache setup and I cannot give you what exactly you need to make it work (it works fine on my vanilla Apache v2.2.17 on Windows).
After rewrite (internal redirect) occurred, it goes to next iteration and Apache starts matching all rules from the top again but for already rewritten URL. If we not add the above line, then mod_rewrite will apply the above rule to rewritten URL form and you will end up with all URLs get rewritten to /index.php with no parameters at all.
If the above will not work, then try the code below:
# do not do anything for already existing files and folders
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1? [R=301,L]
With help of # do not do anything for already existing files and folders rule, mod_rewrite will stop rewriting after URL will be rewritten to /index.php?p1=... format.
In case the above will not work at all (better -- in addition to the above -- I would suggest adding this anyway) use <link rel="canonical" href="FULL_PROPER_RUL"/> in your page:
http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html
http://www.google.com/support/webmasters/bin/answer.py?answer=139394