Forum Moderators: phranque
Quick question for you, I guess you will find this easy, but I can't make it work.
Here is the situation, using a Wordpress blog:
I would like to do about 10 redirections in my .htaccess file.
As examples:
1- redirecting http://www.example.com/index.php3?nom=abc to http://www.example.com/def
2- redirecting http://www.example.com/www/index.php3?php=yyy to
http://www.example.com/zzz
3- http://www.example.com/ddd to http://www.example.com/eee
Since I don't have lots of them to redirect, I don't think I need a complicated redirect, I don't mind hardcoding 10 lines in my .htacess file.
Thanks a lot for your help.
Redirect 301 /index.php3?nom=abc http://www.example.com/def
The 301 does not work, as I still get a 404 without being redirected.
It does work now though for my example #3 (redirecting http://www.example.com/ddd to http://www.example.com/eee) with the following code:
Redirect 301 /ddd http://example.com/eee
So my problem seems to be with the parameters...
The solution is to use mod_rewrite instead of mod_alias, and to check the query string explicitly. Here is an example for your first case:
Options +FollowSymLinks
RewriteEngine on
#
RewriteCond %{QUERY_STRING} ^nom=abc$
RewriteRule ^index\.php3$ http://www.example.com/def? [R=301,L]
In either case, those first one or two lines need only appear once at the top of your "list" of mod_rewrite rule.
Note also that you should not mix mod_alias and mod_rewrite directives on any site which may move to another server in the future. This is because you will have no control over whether that server processes mod_alias directives before processing mod_rewrite directives, or vice-versa. Varying the order of execution can have unexpected (and unpleasant) results on the operation of your server, and that is not something you'll want to be dealing with at the same time as a server move.
The question mark at the end of the substitution (new) URL is not a literal; It is a mod_rewrite token which in this case acts to remove the existing query string from the new URL. It will *not* appear in the redirected-to URL.
See the Apache mod_rewrite documentation and the Apache URL Rewriting Guide for more information. Links to these and to other useful resources are cited in our Forum Charter (see link at top left of this page).
Jim
I'm currently working on a few rewrites and want to remove the parameters from a couple of urls.
Original:
www.example.com/random-category/random-title/?lang=en
New (what i'm trying to achieve):
www.example.com/random-category/random-title/
Please note that the categories and titles may vary and are not fixed (hence the 'random' ;-) ).
I've only come this far:
RewriteCond %{QUERY_STRING} ^lang=en$
RewriteRule ^(.*)$ http://www.example.com? [R=301,L]
So it matches the query string but i already know that my rewriterule is completely off since it redirects the links containing the string to my main page xD
The problem is that i have no clue how to setup the rewriterule for all those random urls.. Could someone nudge me in the right direction?
[edited by: jdMorgan at 11:06 pm (utc) on Jan. 26, 2009]
[edit reason] example.com [/edit]
Replace the question mark with /$1? so that the same URL but without the parameters is the target of the redirect.
Aah ke, i see they are now just following their original links but I got that working without any rewrite rules as well :-P
Note that ^(.*)$ simplifies to (.*) too.
Hmm, i always thought you had to open and close them with at ^ and $ ?
Note that your code won't redirect if lang=en is present but there are additional parameters present.
So what you're saying is that the RewriteCond isn't necessary or is the (.*) not correct?
Not to be an old moldy sock, but the chances of success with mod_rewrite is essentially zero until both regular expressions and mod_rewrite's RewriteRule and RewriteCond directives are thoroughly understood.
"^" means "Starts with" and "$" means "End with." Used in combination, an exact match will be required.
As for the "random-title," it's not clear at what "level" that randomness applies; That is, it isn't clear whether you mean to say that each destination URL is not directly-derivable from the source URL (by adding characters, dropping characters, or re-arranging characters) or not. If the old URL does not contain all of the information needed to construct the new URL, then you'll need one rule per URL (to keep the code simple).
Also, be aware that in order to "change your URLs" you must change them in the links on your HTML pages. Mod_rewrite can be used to map those new URLs (when requested by a client) to the existing server filepaths, and it can be used to tell the search engines to pass the PageRank/link-popularity of the old URL to the new ones more quickly, but it cannot "change the URLs" because URLs are used on the Web and are defined on the Web; Only filepaths are defined (and definable) within the server.
This may be a bit clearer if you realize that the basic *purpose* of a server is to translate URLs defined on the Web to filepaths defined in the server filesystem, and to make the URLs (Uniform Resource Locators) independent of the server's operating system and filesystem conventions.
Jim
RewriteCond %{QUERY_STRING} ^(.+)&virtuemart=[0-9a-z]+$¦^virtuemart=[0-9a-z]+&?(.*)$ [NC]
RewriteRule ^(.*) $1?%1 [R=301,L]
Now this does strip the parameter from the URL, but the resulting URL gives a 404, it seems to append folder structure of my hosting to my url. So instead of redirecting to http://www.example.com/page.html it goes to http://www.example.com/www/htdocs/user/page.html
I know I must be close now... but just can't work this one out!
btw: first post here, Id like to include a thanks for all the help I've gotten from everyone just reading the many topics :)
[edited by: SyntaxTerror at 10:03 am (utc) on May 19, 2009]
The solution is to use two separate RewriteConds. In this case, the values of %1-%9 will be set by the last RewriteCond that matches.
# accept optional parm(s) before virtuemart name/value, but none after
RewriteCond %{QUERY_STRING} ^(([^&]*(&[^&]*)*)&)?virtuemart=[0-9a-z]+$ [OR]
# require parm(s) before and accepts optional parm(s) after virtuemart name/value
RewriteCond %{QUERY_STRING} ^(([^&]*(&[^&]*)*)&)virtuemart=[0-9a-z]+((&[^&]*)*)$
RewriteRule ^(.*)$ http://www.example.com/$1?%2%4 [R=301,L]
It's a bit tricky because the back-references must be "lined up" between the two RewriteConds in order to make sure that %2 and %4 contain the correct parameters in any case, so be careful with the parentheses nesting if you make any adjustments!
Note also that a protocol and a canonical hostname should be specified whenever the [R=30x] flag is used, in order to avoid problems with UseCanonicalName.
Jim
[edit] Corrections as noted below. [/edit]
[edited by: jdMorgan at 4:28 pm (utc) on May 19, 2009]
The bit of code I used originally came from an osCommerce reference elsewhere on the web, I hadn't understood it took into account parameters after or before.
In my case, I always know that ?virtuemart= is the only parameter present in the url, beside page name obviously.
Does this simplify things? Can I take out the second part of my original re-write as so?:
#RewriteCond %{QUERY_STRING} ^(.+)&virtuemart=[0-9a-z]+$ [NC]
#RewriteRule ^(.*) /$1?%1 [R=301,L]
[edited by: SyntaxTerror at 2:07 pm (utc) on May 19, 2009]
However, if you *know* that only the "virtuemart" name/value pair will ever be present, then you could use:
RewriteCond %{QUERY_STRING} ^virtuemart=[0-9a-z]+$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1? [R=301,L]
Jim
[edited by: jdMorgan at 4:44 pm (utc) on May 19, 2009]