Forum Moderators: phranque

Message Too Old, No Replies

Generic rewrite question with subdirectories?

Issue with rewriting Urls with/without directories

         

JPigford

5:00 pm on Nov 6, 2007 (gmt 0)

10+ Year Member



So I'm currently using this rewrite code to give me a fairly flexible way of standardizing my URLs:

RewriteCond %{REQUEST_FILENAME}!-f
RewriteCond %{REQUEST_FILENAME}!-d
RewriteRule ^([0-9A-Za-z_-]+)/?$ /$1.php [L]
RewriteRule ^([0-9A-Za-z_-]+)/([0-9A-Za-z_-]+)/?$ /$1.php?main=$2 [L]
RewriteRule ^([0-9A-Za-z_-]+)/([0-9A-Za-z_-]+)/([0-9A-Za-z_-]+)/?$ /$1.php?main=$2&sub=$3 [L]
RewriteRule ^([0-9A-Za-z_-]+)/([0-9A-Za-z_-]+)/([0-9A-Za-z_-]+)/([0-9A-Za-z_-]+)/?$ /$1.php?main=$2&sub=$3&page=$4 [L]

The problem is if I have subdirectories.

So right now say I've got the following URL:

http://example.com/category.php?main=action

It will be rewritten as:

http:/example.com/category/action

But say I have a file located in a folder like so:

http://example.com/community/forum.php?main=22

How can I make that rewrite code adjust to work for subfolders?

[edited by: JPigford at 5:01 pm (utc) on Nov. 6, 2007]

jdMorgan

7:30 pm on Nov 6, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



We'd need to know what the URL looks like in order to answer.

To further clarify this discussion, mod_rewrite is internally rewriting from your http:/example.com/category/action-formatted URLs to your /category.php?main=action script file, and not the other way around. It is the links on your pages that declare and define the URL, and your server that defines filenames. The user clicks on a link defined on one of your pages, his/her browser requests that URL from your server, then mod_rewrite detects that request and 'sends' it to your script instead of to a static file with the originally-requested name.

Therefore, the answer is to add rules that recognize the 'subdirectory' URLs you describe, and rewrite them to the same (or a different) script with the parameters you need in order for that script to work properly.

By the way, you can shorten and speed up your rules by using the [NC] (no-case) flag to make your pattern comparisons case-insensitive. For example, your last rule above:


RewriteRule ^([0-9a-z_-]+)/([0-9a-z_-]+)/([0-9a-z_-]+)/([0-9a-z_-]+)/?$ /$1.php?main=$2&sub=$3&page=$4 [[b]NC[/b],L]

Jim

JPigford

7:47 pm on Nov 6, 2007 (gmt 0)

10+ Year Member



Eh, I thought I told you want the URL looks like.

http:/example.com/category/action goes to:
http://example.com/category.php?main=action

And then I'd like for
http://example.com/community/forum/22
to go to:
http://example.com/community/forum.php?main=22

Right now I am duplicating that rewrite code and just putting it in the physical "/community/" directory I have.

Maybe I'm just not understanding what you're asking for.

jdMorgan

8:21 pm on Nov 6, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You gave the filepath, not the URL.

The problem here is that there is no way to differentiate between a subdirectory --such as "community"-- and a variable that you want to pass to your script. In other words, there is no programmatic way to tell whether
http://example.com/community/forum/22
should be rewritten to
/community/forum.php?main=22
or instead to
/community.php?main=forum&sub=22

There is no way, based on URL-characterstics alone, to tell a subdirectory-path from what you're calling a 'category'.

Therefore, a solution will require you to re-design your URLs to make this distinction explicit, so that it can be 'detected' by mod-rewrite without requiring you to have separate rules for each category (effectively, a list of all valid category names, so as to distinguish them from subdirectories).

One way to do it would be to use a different separator, such a s a hyphen, for all parameters to be passed to the script, thus leaving the slashes to indicate only directory structure, e.g. http://example.com/community/forum-22

Another way to do it would be to check each slash-separated segment of the URL-path to see if it exists as a subdirectory, and then take the remaining segments as parameters to be passed to your script. This would be very expensive in terms of mod_rewrite overhead (code size and complexity) and CPU utilization (doing multiple 'directory-exists' checks on each and every HTTP request). If you plan to have a very busy/successful site, this is a bad solution.

Jim