mod_rewrite assistance

Discussion in 'Web Design and Development' started by Darth.Titan, Mar 1, 2010.

  1. Darth.Titan macrumors 68030

    Darth.Titan

    Joined:
    Oct 31, 2007
    Location:
    Austin, TX
    #1
    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?
     
  2. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #2
    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.
     
  3. splitpea macrumors 6502a

    Joined:
    Oct 21, 2009
    Location:
    Among the starlings
    #3
    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.
     
  4. Darth.Titan thread starter macrumors 68030

    Darth.Titan

    Joined:
    Oct 31, 2007
    Location:
    Austin, TX
    #4
    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?
     
  5. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #5
    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.
     
  6. splitpea macrumors 6502a

    Joined:
    Oct 21, 2009
    Location:
    Among the starlings
    #6
    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.
     
  7. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #7
    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:
    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
     
  8. Darth.Titan thread starter macrumors 68030

    Darth.Titan

    Joined:
    Oct 31, 2007
    Location:
    Austin, TX
    #8
    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.
     
  9. splitpea macrumors 6502a

    Joined:
    Oct 21, 2009
    Location:
    Among the starlings
    #9
    Great find, angelwatt! I'll be bookmarking that.
     
  10. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #10
    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.
     

Share This Page