views:

127

answers:

3

Hi, I have links like these that I want to change:

mypage.com?page=missions&id=5
mypage.com?page=hello

I tried to change them into easier links with this:

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)$ /index.php?page=$1&id=$2 [L]

It works but if I want to access pages like (mypage.com?page=hello) I have to write:

mypage.com/hello/

and if I write without the slash in the end like this

mypage.com/hello

it doesn't work.

How do I fix it? :)

+3  A: 

This should work:

RewriteRule ^([^/]*)(/([^/]*))?$ /index.php?page=$1&id=$3 [L]

This will make the slash optional by including it in an optional group (denoted by (...)?), along with the optional second half of the query string. Since this introduces a new group between the first and second (left parenthesis determines the order), we have to change the second backreference from $2 to $3.

If the logic becomes much more complex than this, it may be easier to split up the rules.

molf
I understand it and it all seems very logic, but it doesn't work. And I don't get it why. I'm not very experienced with regular expressions , mod-rewrite and .htaccess... Hm
+1  A: 

You could add a second rule that omits the second parameter and optionally the slash:

RewriteRule ^([^/]+)/?$ /index.php?page=$1
RewriteRule ^([^/]+)/(\d+)/?$ /index.php?page=$1&id=$2

This might work too:

RewriteRule ^([^/]+)(?:/(\d+))?/?$ /index.php?page=$1&id=$2

For SEO, you'll probably want to redirect requests missing the slash to the same address with a slash. Use RedirectMatch for that.

Matthew
I tried this too, and it doesn't work. Not even the first code you posted.RewriteRule ^([^/]+)/?$ /index.php?page=$1It only works if I write it that it must have a slash at the end:RewriteRule ^([^/]+)/$ /index.php?page=$1Really weird. I'll try some more and post it here...
Well it should not work. should be a * instead of a + hm. Or?
But it doesn't work with * either
+ means the same thing as * with one exception: it won't match an empty string. I'm not sure why it only works with a slash. I'd have to play around with a running instance of Apache.
Matthew
A: 

I read about the trailing slash with SEO (didn't know about it, thank you mathew!) and the final result was this:

RewriteRule ^([a-zA-Z0-9_-]+)/$ /index.php?page=$1 [L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/$ /index.php?page=$1&id=$2 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ http://www.mypage.com/$1/ [R=301,L]

So now I force it to have a trailing slash.