views:

339

answers:

2

I'm using apache's mod_rewrite to make my application's URL's pretty. I have the basics of mod_rewrite down pat - several parts of my application use simple and predictable rewrites.

However, I've written a blog function, which use several different parameters.

http://www.somedomain.com/blog/
http://www.somedomain.com/blog/tag/
http://www.somedomain.com/blog/page/2/

I have the following rules in my .htaccess:

RewriteRule ^blog/ index.php?action=blog [NC]
RewriteRule ^blog/(.*) index.php?action=blog&tag=$1 [NC]
RewriteRule ^blog/page/(.*) index.php?action=blog&page=$1 [NC]

However, the rules do not work together. The computer matches the first rule, and then stops processing - even though to my way of thinking, it should not match. I'm telling the machine to match ^blog/ and it goes ahead and matches ^blog/tag/ and ^blog/page/2/ which seems wrong to me.

What's going wrong with my rules? Why are they not being evaluated in the way I'm intending?

Edit: The answer was to terminate the input using $, and re-order the rules, ever so slightly:

RewriteRule ^blog/$ index.php?action=blog [NC,L]
RewriteRule ^blog/page/(.*)$ index.php?action=blog&page=$1 [NC,L]
RewriteRule ^blog/(.*)$ index.php?action=blog&tag=$1 [NC,L]

These rules produced the desired effect.

+2  A: 

If you don't want ^blog/ to match anything more than that, specify the end of the input in the match as well:

^blog/$

However, the way many apps do it is to just have a single page that all URLs redirect to, that then processes the rest of the URL internally in the page code. Usually most web languages have a way to get the URI of the original request, which can be parsed out to determine what "variables" were specified, even though Apache points all of them to the same page. Then via includes or some other framework/templating engine you can load the proper logic.

As another note - usually the "more general" rewrite rules are put last, so that things which match a more specific redirect will be processed first. This, coupled with the [L] option after the rule, will ensure that if a more specific rule matches, more general ones won't be evaluated.

Amber
Dav, your 'end of input' part was very helpful. I'll update my question to reflect the answer. Thanks!
EvilChookie
+2  A: 

I think you need to add an [L] after the [NC] statements otherwise it'll carry on even if its already been matched

Mikey
You are correct. I originally had them in my rules, but took them out as a part of stuffing around with it.
EvilChookie