Forum Moderators: phranque

Message Too Old, No Replies

Rewrite in htaccess to Deal with File Extensions

         

jonreynolds

9:28 am on May 20, 2011 (gmt 0)

10+ Year Member



Right, I have been rather blindly fumbling around with htaccess and apache rewriterules to try and make certain things happen depending on what is in the current URL.

In plain talk, what I want is this:

IF URL contains 'jpg' or 'png' or 'gif', upper and lowercase, then make the url do one thing

IF URL does NOT contain 'jpg' or 'png' or 'gif', upper and lowercase, then make the url do another thing.

E.g.s

no image extension:
www.mysite.com/gallery/album1 => www.mysite.com/gallery/index.php?w=album1

image extension:
www.mysite.com/gallery/album1/photo.jpg => www.mysite.com/gallery/preview.php?w=album1&p=photo.jpg

so if it has an image extension, capture everything before the last '/' as w= and everything after thelast '/' (i.e. the photo name) as p=

I had success when it was not an image, i.e. just album level, but adding in the photo rule starts getting confusing.

My latest attempt is this:


Options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_URL} (\.(JPG|jpg|png|gif)$)
RewriteRule ^(.+)/(.+)$ preview\.php?w=$1&p=$2 [L]

RewriteCond %{REQUEST_URI} !^(jpg|png|gif)$
RewriteRule ^(.+)/$ index.php?w=$1 [L


Hope someone can help.

Thanks!

jonreynolds

9:50 am on May 20, 2011 (gmt 0)

10+ Year Member



Hmm, this nearly does what I want:


RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/(.+)$ preview.php?w=$1&p=$2 [L]

RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)/$ index.php?w=$1 [L]


It only falls down in 2 ways;

1. Thumbnails on my page are lost.
2. It only seems to work when I am at least 1 level in; i.e. looking at top level (www.mysite.com/gallery) clicking on an image (www.mysite.com/gallery/photo1.jpg) just goes to the image, but if i am 1 level in (www.mysite.com/gallery/album1) then clicking on an image does go to preview.php!

So nearly there... :)

g1smd

1:12 pm on May 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The .+ part of the patterns is your downfall. The .+ construct is greedy and ambiguous.

You'll need something like
^{[^/]+/}([^/.]+)$
and
^{[^/]+/}([^/.]+)\.(jpe?g|png|gif)$
with the [NC,L] flags instead.

I caution against using the -d "exists" checks if you can avoid it. They are very slow as it invokes a physical disk read in the server.

In your PHP script you'll need to "look" at $1 and strip out /blah/blah/keep-this/ there.

jonreynolds

1:40 pm on May 20, 2011 (gmt 0)

10+ Year Member



Hi, thanks for the reply.

Are you suggesting that I could do what I want with only 2 'rules' or should I still be looking to make use of conditions and then rules?

I am finding it tricky not to think from a php point of view, where one could simply test

'if string contains 'jpg' do this, else do this'

...kind of thing.

This regex is really hurting my brain, but I will keep looking at it.

:)

g1smd

2:12 pm on May 20, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You might be able to use just two rules and no conditions if requests for URL with no trailing slash and no extension are NOT first "grabbed" by the server and redirected to URL ending with trailing slash and mapped to a physical folder.

Test it with and without the -d check on the extensionless ruleset. You certainly don't need it on the extensions rulset.

jonreynolds

2:53 pm on May 20, 2011 (gmt 0)

10+ Year Member



ok I give up, how does your regex work?