Forum Moderators: phranque

Message Too Old, No Replies

URL rewrite exceptions

Querying how to set exceptions when using a blanket rewrite rule

         

cezuk

11:04 am on Jun 5, 2007 (gmt 0)

10+ Year Member



Hi

I'm trying to implement the following URL structure using .htaccess:

User sees:

http://domain.com/layer1/layer2/

Server sees:

http://domain.com/index.php/layer1/layer2

Ive managed to get this working with the following .htaccess file:


RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME}!-f
RewriteCond %{REQUEST_FILENAME}!-d
RewriteRule . /index.php [L]

HOWEVER - inevitably, this rewrites the URL of everything its given.

How would I add an exception? For example, I want a way of expressing this:

IF url = [domain.com...] THEN open the 'forum' folder
ELSE process the rule above (ie, drop 'index.php' into the URL)

Anyone know of a way of doing this? Can it be added to the .htaccess
file I already have, or am I looking like having to find a different
way around it?

Any help would be much appreciated!

- Chris

jdMorgan

1:51 pm on Jun 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Implementing only the specified requirements -- a "two-layer" URL-path ending with a slash, an internal URL-path with "index.php" prepended and the trailing slash removed, and an exception for "/forum/xyz", would give:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !/forum
RewriteRule ^([^/]+/[^/]+)/$ /index.php/$1 [L]

This also eliminates the file-exists and directory-exists filesystem checks, and should be notably faster under load.

Jim

cezuk

3:06 pm on Jun 5, 2007 (gmt 0)

10+ Year Member



Hi

Thanks for the quick reply!

Is there a more generic approach I could take? The reasoning behind the original .htaccess code was that there could be anything between 1-4 layers after the domain (this is the current design, it could well become 5 or 6 in the future) and so I went for the generic "catch all" approach.

I assume that...


RewriteRule ^([^/]+/[^/]+/[^/]+/[^/]+)/$ /index.php/$1 [L]

...wouldn't work because its specifically asking for 4 'layers', and so would ignore anything less?

Could I attempt to ignore the fact its split into layers, and go for something like:


RewriteRule ^([^/]+)/$ /index.php/$1 [L]

Or would I need a different character at the end of the URL so the RewriteRule knows where to stop?

IE, domain.com/layer1/layer2/layer3/#


RewriteRule ^([^#]+)$ /index.php/$1 [L]

I'm clutching at straws here to be honest, any further advice would be much appreciated!

- Chris

jdMorgan

7:45 pm on Jun 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There are many ways to handle the one-to-N directory-levels problem, but this is an efficient implementation, given that you're dropping the final trailing slash:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !/forum
RewriteRule ^(([^/]+/)*[^/]+)/$ /index.php/$1 [L]

Here the inner parenthesized group of "one or more characters Not a slash, followed by a slash" may occur any number of times including zero. It is then followed by an additional non-optional pattern, again of "one or more characters Not a slash, followed by a slash."

Because the entire expression (with the exception of the final trailing slash) is contained in the first layer of parentheses, those matched parts of the URL-path will be available in $1.

Note that the use of negative-match patterns allows an efficient, fast pattern match, unlike ambiguous concoctions of ambiguous "(.*)" patterns.

Jim

[edited by: jdMorgan at 7:46 pm (utc) on June 5, 2007]

cezuk

7:55 am on Jun 7, 2007 (gmt 0)

10+ Year Member



Jim, you_are_a_legend, that worked a treat.

I added an [NC] to the rewrite condition to deal with my dodgy use of capital letters, and now its covering every I need it to.

Thanks for your help! :)