.htaccess RewriteRule help!

Hello, I’m new here and i normally don’t like asking on forums for help as i like figuring out things on my own but this time i thought i’d ask.

I havn’t done much with .htaccess before but what im wanting to do is a simple of rewrite depending on what the URL is.

REWRITE 1: I basically want [noparse]http://www.example.com/about_page[/noparse] to redirect to [noparse]http://www.example.com/page.php?page=about[/noparse] so i wrote the following rule:


Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*)_ page.php?page=$1

PROBLEM: This now works for the ENTIRE website meaning that all images with underscores in the name do not work any more :-(. All images are in a seperate folder /images. So [noparse]http://www.example.com/images/image_file.jp[/noparse] dosnt show. Remove the underscore and it works.

How can I modify this so that anything not being linked in a folder is redirected and anything which is in a folder is not redirected?

EXAMPLES:
[noparse]http://www.example.com/about_page[/noparse] >> [noparse]http://www.example.com/page.php?page=about[/noparse]

[noparse]http://www.example.com/services_pages[/noparse] >> [noparse]http://www.example.com/page.php?page=services[/noparse]

[noparse]http://www.example.com/images/image_file.jpgs[/noparse] >> [noparse]http://www.example.com/images/image_file.jpg[/noparse]

[noparse]http://www.example.com/js/java_v1.js[/noparse] >> [noparse]http://www.example.com/js/java_v1.js[/noparse]

Thanks for your help; it will be much appreciated :D.

Desk_Man

Hi Desk_Man,

Welcome to the SitePoint Apache forum :wave:

What you want to do here is tell Apache that it shouldn’t apply the RewriteRule if a) the requested URL is an existing directory or b) the requested URL is an existing file.
Luckily this can be done very easily with two RewriteConds


Options +FollowSymLinks
RewriteEngine on
# if the request is not for an existing directory ...
RewriteCond %{REQUEST_FILENAME} !-d
# ... and the request is not for an existing file ...
RewriteCond %{REQUEST_FILENAME} !-f
# ... and it contains an underscore, load something else
RewriteRule (.*)_ page.php?page=$1

Two more pointers:

  1. Add the [L] flag to the rule to tell Apache that if the rule matches it shouldn’t test any other rules in this round but start a new round (if this is not clear please say so :))
  2. Try to stay clear of :redhot: (.*) :redhot: as it will nothing and everything and can be very unpredicaple. It’s a lot better to think what characters you will actually need to match and then tailor the rule for that. E.g. to match onlz numbers and digits use ([a-zA-Z0-9]+)
  3. The rule you have right now states “If this is anywhere in the URL …”, while it would be better to say “If the URL starts with …”, i.e., start the rule with a ^

All in all you would get something along the lines of


Options +FollowSymLinks
RewriteEngine on
# if the request is not for an existing directory ...
RewriteCond %{REQUEST_FILENAME} !-d
# ... and the request is not for an existing file ...
RewriteCond %{REQUEST_FILENAME} !-f
# ... and it contains an underscore, load something else
RewriteRule ^([a-zA-Z0-9]+)_ page.php?page=$1 [L]

Does that make sense?

Thank you for your reply and help. Yes your post made sense.

Everything worked fine until i added in the ^ this made the wrong parameters be passed and used so the site stopped working. I removed the ^ and it worked:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([a-zA-Z0-9]+)_ page.php?page=$1 [L]

Many thanks for your help :D.