And today, for my first trick (yes, it is my first trick, but my second post today), I shall transform this URL:
http://www.freshports.org/news/pan2/files.php?message_id=200605010349.k413nOGF019378@repoman.freebsd.org
into
http://www.freshports.org/commit.php?message_id=200605010349.k413nOGF019378@repoman.freebsd.org&category=news&port=pan2&files=yes
Why? Because it is impolite to break existing URLs. It is far better to redirect them to the new improved content.
Our documentation for today’s exercise shall be http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule.
Our first attempt at fixing this is:
RewriteRule ^(.*)/(.*)/files.php?(.*) /commit.php?message_id=$3&category=$1&port=$2&files=yes [R=permanent]
This fails. I get this:
http://beta.freshports.org/commit.php?message_id=&category=/news&port=pan2&files=yes
Why? Because I didn’t understand that RewriteRule can inspect the REQUEST_URI, not the QUERY_STRING. So what I needed to so is add QSA to my flags and remove message_id=$3 from the target. Like this:
RewriteRule ^/(.*)/(.*)/files\.php$ /commit.php?category=$1&port=$2&files=yes [R=permanent,QSA]
There, now we get redirected to the right place!
However, the query string parameters are not in the same order as existing URLs. What to do! OH WHAT TO DO!
Simple. Redesign the existing URLs. Why? For consistency. I would prefer to have URLs of the form:
http://www.freshports.org/commit.php?message_id=200605010349.k413nOGF019378@repoman.freebsd.org&category=news&port=pan2&files=yes
But this will do:
http://www.freshports.org/commit.php?category=news&port=pan2&files=yes&message_id=200605010349.k413nOGF019378@repoman.freebsd.org
Why do I want it consistent? Easier to read. And perhaps search engines won’t be pulling down the same page multiple times just because the query string parts differ in order. It’s hard enough to write a search engine without comparing query strings.
My thanks to DrBacchus on #apache for pointing out the error of my ways.
Done. Ship it.