Forum Moderators: phranque

Message Too Old, No Replies

Help modifying one query parameter

         

lat9

12:43 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



I'm in the process of restructuring my site and need to redirect all requests of the form

www.example.com/index.php?main_page=index&cPath=1(+additional parms)

to

www.example.com/index.php?main_page=index&cPath=6(+additional parms)

What I've tried in my .htaccess file is

RewriteRule ^/index\.php?main_page=index(&cPath=1)(.*)$ /index\.php?main_page=index&cPath=6$2 [L,R=301]


... but that doesn't work, in fact it doesn't redirect at all. I *thought* that the (&cPath=1) would wind up being $1 (so I can lose it) and that $2 would be the remaining arguments.

sublime1

2:15 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



Two issues:
1) the match value in the RewriteRule is just the path -- it doesn't contain the query string parameters. To get at this you can use a RewriteCond with one of the special variables, such as %{REQUEST_URI} that has the query string in it (see Apache 2.2 doc, I think there's one with just the query string) -- then you can do the pattern to "capture" the part your query string you need to change. Whereas $1 can be used to back-reference captured values from the RewriteRule, %1 can be used (in the following RewriteRule) to back reference values captured in the RewriteCond ... in this case, your query string.

The trick is that normally RewriteRule passes along the full query string, if you are adding or modifying the query string, you'll probably need to use the QSA flag ("query string append"). What I am not quite sure about is whether this is just for adding to existing query strings -- there's likely a way to say "don't pass the query string" and just add the full, corrected version to your rewritten URL.

One note: your current RewriteRule assumes these changes are not made in a .htaccess fie (instead, in a VirtualHost or server context); in .htaccess, the rewrite engine will strip off the leading slash. Make sure to add it back (as you have in your example) on the rewritten URL.

Tom

lat9

3:00 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



OK, I tried to use the RewriteCond/RewriteRule

RewriteCond %(QUERY_STRING) ^main_page=index&cPath=1(.*)$
RewriteRule .* /index\.php?main_page=index&cPath=6%1 [L,R=301]


... but that isn't working either. I modified my httpd.conf to get a rewrite.log file and am getting the message

RewriteCond: input='%(QUERY_STRING)' pattern='^main_page=index&cPath=1(.*)$' => not-matched


when my URL is www.example.com/index.php?main_page=index&cPath=1.

I don't understand why it's not matching.

lat9

3:53 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



I'm getting closer ... I had the QUERY_STRING surrounded by parentheses instead of squigglies. The rewrite directives are now

RewriteCond %{QUERY_STRING} ^main_page=index&cPath=1(&?.*)$
RewriteRule ^(.*) http://www.example.com/index\.php?main_page=index&cPath=6%1 [R=301,L]


and the following redirect properly

www.example.com/index.php?main_page=index&cPath=1

=> www.example.com/index.php?main_page=index&cPath=6

www.example.com/index.php?main_page=index&cPath=1&page=3

=> www.example.com/index.php?main_page=index&cPath=6&page=3

... but (arggh) this doesn't

www.example.com/index.php?main_page=index&cPath=11

=> www.example.com/index.php?main_page=index&cPath=61

How do I code the regex to have the condition kick in on &cPath=1 but not on &cPath=11 or &cPath=111, while keeping the remaining parameters?

lat9

4:45 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



OK, finally ...

RewriteCond %{QUERY_STRING} ^main_page=index&cPath=1([^0-9]|&?.*)$
RewriteRule ^(.*) http://www.example.com/index\.php?main_page=index&cPath=6%1 [R=301,L]


I don't know if this is the most efficient way for this to work, but something is better than nothing.

g1smd

6:23 pm on Oct 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I would replace the ^(.*) with ^(index\.php)?$ so that it only looks for a query string when the path isn't to an image, stylesheet or script file.

jdMorgan

7:22 pm on Oct 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Still a few remaining ambiguities that could cause errors. I'd suggest:

RewriteCond %{QUERY_STRING} ^main_page=index&cPath=1(&.*)?$
RewriteRule ^(index\.php)?$ http://www.example.com/index\.php?main_page=index&cPath=6%1 [R=301,L]

This makes the ampersand and parameters following cPath=1 optional, but accepts only exactly cPath=1 and not cPath=11 or =111, etc. regardless of whether an ampersand and additional parameters follow.

It also incorporates g1smd's suggestion above to limit the rule's scope to requests for URL-path "/index.php" or just "/".

Jim

lat9

7:34 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



Thanks, Jim and Glenn. I'll incorporate your suggestions.