Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Darth.Titan

macrumors 68030
Original poster
Oct 31, 2007
2,908
754
Austin, TX
I thought I'd throw this out in case anyone was able to help, but I'm not going to hold my breath.

We have a site that we're migrating to a new URL. The problem is this is a pretty frequently bookmarked and visited site and we want to make the transition as seamless as possible. I'm pretty sure the correct RewriteRules will do it but I'm stumped
Code:
RewriteCond %{QUERY_STRING} ^dir=category1$
RewriteCond %{QUERY_STRING} ^pageid=([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$
RewriteRule ^(.*) http://newsite.com/display.php?id=%2 [R=301,L]
Okay, so let me explain: on the current site, we want to redirect all content under the category category1 to the new site. (See the first RewriteCond) The category is passed via the URL, and there are several categories, but only one is moving.

I need to capture the pageid of the page requested to pass to the new site. (See the second RewriteCond) Again, the pageid is passed via the URL, and we have been careful to synchronize the pageids between the two sites.

The RewriteRule I hope is fairly self explanatory. I want to redirect all requests meeting the two conditions to the new url with the proper id.

Is there any chance that there is anyone here that can tell me why this is not even close to working?
 
The why it is not working is easy enough. Your two query_string lines both check that the query starts with something different. Both conditions cannot be true at the same time. Using the ^ means that is where the query starts. I'm not sure if the category and pageid are part of the same query or not so I'm not sure how the fix will look.

If you need to look at "or" case between two different query strings, then add [OR] to the end of the first line. Then if either of those first two lines matches, then the third line will execute what it can.

Also, the captured portion in the second line cannot be accessed in the third line. Your rewrite line will need to have the regex to capture the pageid portion.

So mostly, get rid of the ^ and & in there.
 
What angelwatt said, except that I'd add that the "$" indicates the end of the query string, so in each case you're checking that there's nothing else in the query string but what's in that case. If you want the check to be that the query string specifies both that category and one of those page IDs, remove both the "^" and the "$" signs from both conditions.
 
Yeah that's a good call. That's what I get for copying and pasting an old version...

The problem seems to have been that nothing was working at all regarding the QUERY_STRING. I even tried redirecting everything with any query string at all. Nada.

Eventually I discovered an .htaccess file in a child folder that was keeping the root .htaccess renames from happening. I moved the child's content to the root and seem to be having some luck, but I've still got a snag.
Code:
RewriteCond %{QUERY_STRING} dir=category1
RewriteCond %{QUERY_STRING} pageid=([0-9]*)
RewriteRule ^(.*) http://newsite.com/display.php?id=$2

That mostly works, but the second ReWriteCond doesn't appear to be getting the pageid to use in the redirect. Now what's wrong?
 
That mostly works, but the second ReWriteCond doesn't appear to be getting the pageid to use in the redirect. Now what's wrong?

What do you think $2 is? You only have one set of parens on your rewrite line so only $1 exists. Like I mentioned earlier, those captures only exist on a given line, not across lines. Give this a try.

Code:
RewriteCond %{QUERY_STRING} dir=category1
RewriteRule ^(.*)pageid=([0-9]{1,3}) http://newsite.com/display.php?id=$2

This assumes the page id is between 1 and 3 characters long. If you need higher values that's an easy fix. If you're continuing to have problems, seeing some example URLs may be helpful.
 
Yeah that's a good call. That's what I get for copying and pasting an old version...

The problem seems to have been that nothing was working at all regarding the QUERY_STRING. I even tried redirecting everything with any query string at all. Nada.

Eventually I discovered an .htaccess file in a child folder that was keeping the root .htaccess renames from happening. I moved the child's content to the root and seem to be having some luck, but I've still got a snag.
Code:
RewriteCond %{QUERY_STRING} dir=category1
RewriteCond %{QUERY_STRING} pageid=([0-9]*)
RewriteRule ^(.*) http://newsite.com/display.php?id=$2

That mostly works, but the second ReWriteCond doesn't appear to be getting the pageid to use in the redirect. Now what's wrong?

I think there may be two things going on here.

One is, I'm not sure RewriteRule even looks at query strings (there's a reason for the QSA (querystring append) option).

Secondly, as angelwatt said, you're capturing the entire request string in your RewriteRule, and it only has one back-match (to "(.*)"). Nothing you match in a RewriteCond is available to the RewriteRule. You have to match it explicitly in the RewriteRule.
 
One is, I'm not sure RewriteRule even looks at query strings (there's a reason for the QSA (querystring append) option).

I wasn't certain either so had to look it up. And the answer is no, it cannot. So, my suggestion above won't work. From this Apache page under the RewriteRule section:
apache.org said:
Note: Query String
The Pattern will not be matched against the query string. Instead, you must use a RewriteCond with the %{QUERY_STRING} variable. You can, however, create URLs in the substitution string, containing a query string part. Simply use a question mark inside the substitution string, to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine a new query string with an old one, use the [QSA] flag.
The only other idea I can think of for you is to use something like PHP to analyze the URL and create a new one to pass user's along. It's a bit more effort in comparison to RewriteRules, but not sure what else can be done.

Edit:
Looks like we may have been wrong about using captured pieces across lines. According to this posting it can be done, though it uses % rather than $ in front of the number. In your setup, it'll still be 1 rather than 2 though. I haven't tried the solution so see if it works, or which version of Apache web server it works on.

So maybe:
Code:
RewriteCond %{QUERY_STRING} dir=category1
RewriteCond %{QUERY_STRING} pageid=([0-9]*)
RewriteRule ^(.*)$ http://newsite.com/display.php?id=%1
 
Edit:
Looks like we may have been wrong about using captured pieces across lines. According to this posting it can be done, though it uses % rather than $ in front of the number. In your setup, it'll still be 1 rather than 2 though. I haven't tried the solution so see if it works, or which version of Apache web server it works on.

So maybe:
Code:
RewriteCond %{QUERY_STRING} dir=category1
RewriteCond %{QUERY_STRING} pageid=([0-9]*)
RewriteRule ^(.*)$ http://newsite.com/display.php?id=%1

Holy variable identifier Batman, that did the trick! It does seem to be working now!

I'm really not stupid (I promise), but for some reason RegExes give me fits. I knew what I wanted to do was possible, and I've been reading Google all day trying to figure it out for myself. I appreciate having a couple of extra brains to help. splitpea, angelwatt, you guys are aces in my book.

angelwatt why does it seem that you know everything about everything where web design, development, etc. are concerned? I want to be just like you when I grow up!

Thanks again guys, really. I feel like I learned a lot today.
 
angelwatt why does it seem that you know everything about everything where web design, development, etc. are concerned? I want to be just like you when I grow up!

Haha, patience and developing strong Google-fu. Web development is a hobby I enjoy, so I do a lot of reading on it as a break from my day job. Hanging out around the forum helps a lot too because I find people doing a lot of things I would never have thought of doing and so it makes me go beyond my comfort zone and learn about new things. And occasionally, I find what I think I know about something, is wrong, so I get to fine tune my knowledge. Glad the rewrite works now. Regex has such a simplicity and complexity, just like rewrites.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.