homepage Welcome to WebmasterWorld Guest from 54.161.175.231
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
301 Redirect with Path Arguments to None
Old URLs had arguments, new ones do not
ccDan




msg:3663796
 7:28 pm on May 31, 2008 (gmt 0)

I'm trying to get a site moved from one server to another, and I cannot get the 301 redirects working at all.

I need to go from this: www.domain.dom/blog-archive.php?page=20080531-road-trip

to this: www.www.domain.dom/2008/05/31/road-trip/

I've tried several methods (found in different Google searches) but they all result in a 404 page not found error. The destination page does show up fine if I enter the URL directly. And, to test that the redirect otherwise working, I tried a page (that doesn't exist) without any path arguments, and the redirection worked just fine:

Redirect 301 /test.php [domain.dom...]

This is what I've been (most recently) using to try to redirect the page with path arguments:

Redirect 301 /blog-archive.php?page=20080531-road-trip [domain.dom...]

I've tried escaping different characters to no avail.

Any ideas on how to get this to work?

 

jdMorgan




msg:3663855
 9:34 pm on May 31, 2008 (gmt 0)

You can't do it with mod_alias. Use mod_rewrite, use a RewriteCond to examine THE_REQUEST, and then append a "?" to the substitution URL to clear the incoming query string.

However, this is the third of three steps, and you haven't mentioned the first two (and more-important) steps at all.

See this thread [webmasterworld.com] for details.

Jim

ccDan




msg:3663858
 9:45 pm on May 31, 2008 (gmt 0)

Huh? First two steps? I'm just trying to do a redirect as I've moved from one server to another.

The old server used this structure for URLs:

www.domain.dom/blog-archive.php?page=20080531-road-trip

The new server uses this URL for the new page with the same content:

www.domain.dom/2008/05/31/road-trip/

I'm unclear what rewriting would do, as "www.domain.dom/blog-archive.php?page=20080531-road-trip" doesn't exist at all on the new server.

jdMorgan




msg:3663863
 9:51 pm on May 31, 2008 (gmt 0)

Very well, then use mod_rewrite, and a RewriteCond to examine the query string. Append a "?" to the substitution URL to clear this incoming query string, after back-referencing the values you need in the substitution URL.

Using this method, it appears that only a single RewriteRule will be needed.

[added] If you are not changing domain names, then I recommend that you read and understand that cited thread carefully before rushing off to make a change. It is likely that the method in that thread is exactly what you need to do, and if you simply do a redirect (as described here in this thread), you'll have trouble.

You say "the new server uses URLs like this," but in fact, the server doesn't care what the URL is. If you use the wrong method, then the SEF plug-in code that you very likely have on that new server and your redirect will likely interfere with each other, causing an "infinite" rewrite/redirect loop. And in that case, the method in the cited thread is precisely what you need to fix the problem. The SEF plug-in would be "step 2" in the cited thread.[/added]

Jim

[edited by: jdMorgan at 10:00 pm (utc) on May 31, 2008]

ccDan




msg:3663883
 10:38 pm on May 31, 2008 (gmt 0)

Thanks, but I'm just not seeing where any of that really helps me. The path arguments from the old server aren't anything that I can convert into the new URL structure on the new server.

For example, in the URL "blog-archive.php?page=20080531-road-trip" the path argument for the page variable is "20080531-road-trip" which I cannot break down. (I'm sure there's probably a way to break that down somehow, but still the final bit, the "road-trip" part may not necessarily associate with the text for the new URL structure.)

In this example, the new URL is "http://www.domain.dom/2008/05/31/road-trip/" but that's just in this case. In another URL, the path argument may have been something like "20080530-new-rental" and the new URL might be something like "http://www.domain.dom/2008/05/30/new-rental-car/" or even something where the text doesn't associate at all.

So, as I see it, I cannot do a rewrite rule that changes one pattern to another because there isn't necessarily a pattern that can be extracted from the old path arguments.

I think that I would need some way of hardcoding each URL to redirect to the new URL.

Here is what my .htaccess file looks like without any of the aforementioned attempts at redirection:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.domain.dom$
RewriteRule ^(.*)$ [domain.dom...] [R=301]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

jdMorgan




msg:3663888
 10:55 pm on May 31, 2008 (gmt 0)

Ah... You did not say anything about changing the file structure, you said you were changing servers.

You can use the "examine QUERY_STRING" method then.

Put individual rules for the old URLs that "don't associate" first, then follow with a generic (e.g. "new-rental-car" rules first, a generic to map "road-trip" and other directly-associatable URLs)

Where that thread may help you is in demonstrating regex pattern and back-reference usage for the directly-associatable URLs.

If you have a ton of individual rules, there's a trick you can use to make the code 50% more compact. That's details, though, and can wait until you get a few basic rules working.

Jim

ccDan




msg:3663899
 11:30 pm on May 31, 2008 (gmt 0)

Got it!

RewriteCond %{query_string} ^page=20080531-car-ride$
RewriteRule ^blog-archive\.php$ [domain.dom...] [R=301,L]

Thanks!

jdMorgan




msg:3663946
 1:31 am on Jun 1, 2008 (gmt 0)

Yes, but in general, don't take ANY liberties with capitalization, spelling, spacing, or punctuation, compared to the documentation. We've seen evidence of 'picky servers' here in this forum.

Here's what the whole pile should look like, with various corrections/clean-ups:

# Specific redirect
RewriteCond %{QUERY_STRING} ^page=20080531-car-ride$
RewriteRule ^blog-archive\.php$ http://www.example.com/2008/05/31/road-trip/? [R=301,L]
#
# Catch-all at the end for directly-associated URLs
# (e.g. blog-archive.php?page=20080531-road-trip -> /2008/05/31/road-trip/)
RewriteCond %{QUERY_STRING} ^page=([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^blog-archive\.php$ http://www.example.com/%1/%2/%3/%4/? [R=301,L]
#
# Redirect any other non-canonical requests to canonical domain
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
#
# WP internal rewrite code
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Again, if you have more than a dozen "specific URL" redirects, let me know. There's a trick to save some code, but it's difficult to read and write -- and kind of ugly. If you have hundreds of redirects, and have access to httpd.conf, then a RewriteMap would be even better.

Jim

ccDan




msg:3664002
 3:40 am on Jun 1, 2008 (gmt 0)

Thanks!

I have about a dozen of two different sets of pages. The first set is on the blog-archive.php page and the other is on a page.php page. With that second set, the path argument value begins with a letter, as in a20080531-title-text. So, for those, would I do something like this:

RewriteCond %{QUERY_STRING} ^page=([a-z]{1})([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

ccDan




msg:3664004
 3:47 am on Jun 1, 2008 (gmt 0)

Actually, on both blog-archive.php and page.php, I have mixed path arguments. Some have the letter in front; some don't.

Am I right that I would need to do:

RewriteCond %{QUERY_STRING} ^page=([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%1/%2/%3/%4/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page=([a-z]{1})([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

RewriteCond %{QUERY_STRING} ^page=([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^blog-archive\.php$ http://www.example.com/%1/%2/%3/%4/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page=([a-z]{1})([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^blog-archive\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

jdMorgan




msg:3664261
 3:36 pm on Jun 1, 2008 (gmt 0)

If you intend to "discard" the prepended letter, then only one rule per "set" would be required. Example of the first two rules in your immediately-previous post compressed to one rule:

RewriteCond %{QUERY_STRING} ^page=[b]([a-z])?[/b]([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^page\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

BTW, "[a-z]{1}" is redundant, I just replaced it with "[a-z]", which matches one character by default.

Also, if "blog_archive.php" and "page.php" are now to be redirected to the same static URL-set, then you can combine all four rules above into one:

RewriteCond %{QUERY_STRING} ^page=([a-z])?([0-9]{4})([0-9]{2})([0-9]{2})-(.+)$
RewriteRule ^(blog_archiveŠpage)\.php$ http://www.example.com/%2/%3/%4/%5/? [R=301,L]

Replace the broken pipe "Š" character with a solid pipe character from your keyboard before use; Posting on this forum modifies the pipe characters.

Jim

ccDan




msg:3664304
 5:39 pm on Jun 1, 2008 (gmt 0)

Thanks much!

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved