Problem with [L]

I am trying to re-organize my website, and while testing some changes to my mod_rewrites, am not getting the outcome I’d expect?!

In English, here is what I want…

If a user tries to go to the “Finance” section (pretty URL)…

http://local.debbie/finance/

…then I want them to be taken to a new “Finance Home Page”, which would be this file…

http://local.debbie/finance/index.php

However, if a user navigates to any other section (e.g. Legal, Management, etc)…

http://local.debbie/legal/

http://local.debbie/management/

…then my original mod_rewrite should kick in, and they would be taken here…

http://local.debbie/articles/index.php?section=legal

http://local.debbie/articles/index.php?section=management

(BTW, what my original code is trying to do, is this… Take a look at the Section the user clicked on, and send that to the “template” file at “articles/index.php” which in turn populates the “template” with all articles from the database related to that Section.)

Does that make sense so far?

So here is how I modified my mod_rewrite, thinking it would work…


#PRETTY:		finance/
#UGLY:			articles/index.php?section=finance

#Rewrite only if the request is not pointing to a real file (e.g. add-comment.php, index.php).
RewriteCond %{REQUEST_FILENAME} !-f

#New Code looking just for "Finance" section...
RewriteRule ^/finance/$ finance/index.php [L]

#Match any kind of Section.  PHP will decide if it's valid or not.
RewriteRule (.+)/$ articles/index.php?section=$1 [L]

When I use that mod_rewrite, it is as if the new line I added doesn’t exist. As such, when you go to…

http://local.debbie/finance/

…you are taken to a page which lists all Finance Articles (old way) versus my new “Finance Home Page” which is a new “index.php” file located in my new “finance” directory in the Web Root.

It appears my [L] switch thingy - or whatever it is called - is not working?! :-/

Hope all of that makes sense?! :blush:

Sincerely,

Debbie

Your match is likely incorrect, changes are the beginning slash should not be there. Try the following

RewriteRule ^finance/$ finance/index.php [L]

Secondly, I don’t know why you need that rewrite rule to begin with, you are performing an action Apache will do by default. Granted I guess you would need this rule if you are not applying any RewriteCond that tell it NOT to run the rule if there is a physical file or directory already established with that path.

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

I took your two different approaches, and both seem to have fixed things.

Now can you help me understand why your code works?! :lol:

Approach #1:
For my original approach, why does this work…


RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^finance/$ finance/index.php [L]

…but this doesn’t…


RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/finance/$ finance/index.php [L]

Since “finance” is starting at the Web Root, I would think either would work?!

BTW, I originally had it like this…


RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule /finance/$ finance/index.php [L]

…to disallow URL’s like this…

http://local.debbie/TEST/finance/

Approach #2:


RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

#Match any kind of Section.  PHP will decide if it's valid or not.
RewriteRule (.+)/$ articles/index.php?section=$1 [L]

Why is it that if I go to…

http://local.debbie/finance/

…then I am routed to…

http://local.debbie/finance/index.php

But if I go to, say…

http://local.debbie/legal/

…then I am routed to…

http://local.debbie/articles/index.phph?section=legal

I don’t see how your code above distinguishes between these two URL’s…

http://local.debbie/finance/

http://local.debbie/legal/

Sincerely,

Debbie

Okay, for Approach #1

Apache 2 and later no longer includes the slash following the host name in the REQUEST_FILENAME (it may have never included it, but for some reason I believe this was a change in Apache 2). So since REQUEST_FILENAME does can NEVER contain a beginning slash, that is why your rules starting with a forward slash fail.

Now your second rule in Approach #1 “RewriteRule /finance/$ finance/index.php [L]” would likely work for “http://local.debbie/TEST/finance/” but would not work for “http://local.debbie/finance/”. Why? Because of the starting slash. Changing it to “RewriteRule /?finance/$ finance/index.php [L]” would theoretically work as it makes the start slash optional, however it would also pick up “http://local.debbie/business-finance/”.

Approach #2 works because there is no physical directory or file named legal/ or legal/index.php, since neither of those exists, it tries to match it against “RewriteRule (.+)/$ articles/index.php?section=$1 [L]”, which is successful, as that is a catch-all rule.

finance/ and finance/index.php do have a physical directory/file, and thus do NOT pass the rewrite conditions that state the requested URL must not have a physical directory/file present on the web server, therefore they never attempt to run the rewrite rule.

Getting really confused here…

I forgot that I just created a directory called “finance” and dropped a test “index.php” in it. So I can see why your 2nd code example works, however, I don’t think this will work for what I am trying to do ultimately…

Rewind…

The way my website is currently coded (i.e. Apache mod_rewrites, PHP, etc) is that I have a Navigation Bar with several “Sections” in it.

A user clicks on something like “Finance” which goes to…

[INDENT](Pretty URL) http://local.debbie/finance/
(Redirect) http://local.debbie/articles/index?section=finance
[/INDENT]

…and displays a listing of articles about Finance.

This works great, except that right before going live with v2.0, I realized that as I add content to my website, I am going to have more than just “Articles” in a given Section. (For example, maybe I want to have Graphs/Charts or Stock Quotes in my “Finance” section.)

So the only practical way to handle this - as I see it - is to create a “Landing Page” for each Section.

To further complicate things, each “Landing Page” will require different code, so having a “catch-all template” like I am using now to display the “Listing of Articles” won’t work.

So originally I figured I would just create a new directory for each Section, and then I could create a unique “index.php” file, and be good to go.

However, I also wonder if there is a better way. (I’m not crazy about mucking up my Web Root with “shell” directories to solve this issue.)

And the code you just offered wouldn’t work moving forward, because if I follow the approach just described, then I would have directories for “Finance”, “Legal”, “Management”, etc and so if I wanted to have a Section without a “Landing Page” that went directly to a “Listing of Articles” using my current articles/index.php template, then things wouldn’t work.

I think my bigger questions needs to be…

1.) Should I create directories for each Section of my website (i.e. maybe 10-15)?

2.) Depending on #1, how do I handle the need for a unique PHP file to create the various “Landing Pages”?

3.) How hard would it be to have some Sections go to a “Landing Page”, but other Sections go directly to the “Listing of <Section> Articles” page for Sections that don’t have enough material/content to justify creating a “Landing Page” in the beginning?

Lots of questions, I know?!

Anyways, that is what I am ultimately trying to do, and I’m not sure if this is more of a File System/Apache thing, or more of a Code/PHP thing?

Thanks,

Debbie

My personal suggestion, don’t create directories. Use your global catch all and handle these scenarios in your routing page. Detect that they requested a section and handle it accordingly. This gives you full control and you can still send some sections to one place, and others to another place without altering your htaccess.

Off Topic:

I could supply the references to clear this up, if you’d like.

Here’s the Apache 2 reference documentation for mod_rewrite. Scroll to the end, to the two tables just before the comments. Those tables describe how rewrite rules behave when in a per-server context (where rules must match a leading slash) vs a per-directory context (where rules must not match a leading slash). Basically, when in a per-server context, rewrite rules match on the absolute path, which includes the initial slash. And when in a per-directory context, rewrite rules match on a relative path, relative to the directory in which the rules reside, which means no leading slash.

Then, you can also double check the Apache 1.3 reference documentation for mod_rewrite. Scroll most of the way down to find the same tables. The per-server and per-directory behavior was the same in Apache 1 as it is in Apache 2.

If you wanted to be certain beyond all doubt, you could download Apache 1.3 and try all the scenarios.