views:

46

answers:

2

I'm writing a mod_rewrite rule and would like a hand making it do what I want.

Basically I want the following cases to work:

request | Redirect to
---------------------
cheese  | /?page=cheese
abc123  | /?page=abc123
abc/def | /?page=abc/def
a/b/c/d | /?page=a/b/c/d

(Any alphanumeric plus . - / and _ redirected)

With two special cases:

request | Redirect to
------------------------
admin   | don't redirect
media   | don't redirect

With these two I don't want any sub directories etc to redirect either.

I've got as far as:

RewriteRule ^([A-Za-z0-9-_]+)/$ /index.php?page=$1 [L]

But this only satisfies the top two tests.

Any ideas?

+1  A: 

If your version supports it, you can you use a negative lookahead:

^(?!(?:admin|media)$)([A-Za-z0-9-_]+)/$

Now, I'm no sys admin, but you can probably have an earlier rule to match admin and media, which is probably an easier idea.

Kobi
Looks like you can, depending on the version: [Regex negative look-ahead is not working for mod_rewrite between different Apache versions](http://serverfault.com/q/120971/2454)
Kobi
Oh, I also want to fail on `adminACB`, simply remove the `$` sign from the lookahead: `(?!admin|media)`
Kobi
I like this, though I'm gonna go with the other answer as I think it's more maintainable as time goes on. Thanks a lot though!
Rich Bradshaw
+2  A: 

I would create a separate earlier rule (as Kobi also suggested) and use the RewriteRule dash directive to prevent substitution.

A dash indicates that no substitution should be performed (the existing path is passed through untouched). This is used when a flag (see below) needs to be applied without changing the path.

^index.php - [L]
^(admin|media) - [L]
^([A-Za-z0-9-_/\.]+)$ /?page=$1 [L]

(I wasn't able to test this where I'm at right now, so you might need to edit this slightly - sorry .. but the idea should be clear)

Tested on Apache 2.2


EDIT: Was able to try this out now - needed to add the [L] to make it work.
EDIT2: Realized I didn't answer the full question, added rules for the rest of the stuff.

Lauri Lehtinen
Cool - didn't know about the dash! Seems that visiting /admin/ doesn't go to the same place as /admin/index.php (It does without any rewrite rules...)
Rich Bradshaw
Where's /admin/ going? Do you have both index.html and index.php located under /admin? If you do, and index.html appears before index.php in Apache's DirectoryIndex config directive, that might be causing problems.
Lauri Lehtinen