views:

29

answers:

1

I have a bootstrap php file that I am routing all requests through:

RewriteRule ^(.*)$ index.php?query=$1 [L]

Say I have a url like /books/moby-dick, but I need the URL to pass to the index file like /books/detail/moby-dick. Is there a way to "rewrite" /books/moby-dick to /books/detail/moby-dick before the last RewriteRule? I thought the Chain [C] flag would do it but I end up with "books/detail/moby-dick/moby-dick". Here's where I'm currently stuck:

RewriteRule ^books/([A-Za-z0-9\-]+)$ books/detail/$1 [C]
RewriteRule ^(.*)$ index.php?query=$1 [L]
+1  A: 

Any rewrites that you perform will automatically flow down to subsequent rules in your rule set provided that you don't cause the process to end/restart with the L (which typically restarts when used in .htaccess) or N flag. You could remove the chaining and it would still work, although in that case you'd have to condition the second rule:

RewriteRule ^books/([A-Za-z0-9\-]+)$ books/detail/$1

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?query=$1 [L]

Note that if you do chain the rules together, if the request path does not match the first rule, the request won't be redirected to the bootstrap file.

None of that is the cause of the actual problem though. What happens is that Apache has decided that the request has path info (for reasons I'll have to look into), and after your rewrite it automatically appends that to the result. The supposed "path info" is /moby-dick, which is why it ends up appearing twice.

Luckily, since we didn't want it in the first place, we can discard it with the DPI flag. Keeping the above points in mind, the following will redirect a request to books/moby-dick to index.php?query=books/detail/moby-dick:

RewriteRule ^books/([A-Za-z0-9\-]+)$ books/detail/$1 [DPI]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?query=$1 [L]

(I made the assumption you wanted books/detail/name, although you also mentioned books/view/name)

Tim Stone
DPI looks like what I've been looking for. Great answer!
Typeoneerror