RewritesRule

February 9, 2007

For my thesis, I’m building a simple (there’s that word again!) publishing backend that basically just accepts any kind of media, gives you an interface to catalogue it, creates Torrent metafiles, etc and then spits out XHTML and RSS. For this to look nice, I decided to use Apache’s mod_rewrite to use simple canonical URI’s (like show/get/11, genre/Horror etc), so my rule looked something like this (L flag means it’s the last rule and NC that the regex is case-insensitive)

RewriteRule ^([a-z]+)/(.*)? shows.php?p=$1&id=$2 [L,NC]

But then you hit the age-old problem. You have some files (like images, css, javascript etc) that you want the browser to access directly, without the redirect. I must have tried a bazillion different permutations of Rewrite conditions, but then ended up with these two:

RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{REQUEST_FILENAME} !-f

Which, put before your RewriteRule, simply say:

Only apply the rule if the accessed file or directory doesn't exist on the server

Perfect. Mind you, there’s also a “-U” switch which the Apache docs say should do the same thing, but I simply couldn’t get it to work.

A really good way to learn these is to, in your httpd.conf set:

RewriteLog /private/var/log/httpd/rewrite_log

RewriteLogLevel 9

And just follow the output of that while your working on these.

Here’s also some good practical RewriteRule documentation.Oh, and there’s also a handy RewriteRule cheatsheet over at ILJD.