Rewrite Rule with Sub folders

Discuss practical ways rearrange URLs using mod_rewrite.

Rewrite Rule with Sub folders

Postby deamon » Wed Mar 25, 2009 4:11 am

Hi,

I have this CMS with bad URLs that I want to fix. Here's what I have:

Code: Select all
http://host/?p=index&id=234&extraparam=123&anotherparam=234


I want to reformat it like: (simply enclose the page name in slashes)

Code: Select all
http://host/index/id=234&extraparam=123&anotherparam=234 (and any extra parameters will be appended to the URL string).


I just want the "page" parameter to be enclosed with slashes. But one thing that keeps me from successfully get this working is I have folders too:

http://host/folder1/ is a derived sub application of the root one, that means it can have the same parameters:
Code: Select all
http://host/folder1/?p=index&id=234&extraparam=123&anotherparam=234.


So with the URL rule, it would like to make it look like: http://host/folder1/index/id=234&extrap ... rparam=234 like described above for any sub folders, not just "folder1".
deamon
 
Posts: 16
Joined: Thu Jul 20, 2006 9:13 pm

Postby richardk » Wed Mar 25, 2009 3:31 pm

/index/id=234 or /index/?id=234?

Try
Code: Select all
Options +FolowSymLinks

RewriteEngine On

# Ignore existing files.
RewriteCond %{SCRIPT_FILENAME} !-f
# Ignore existing directories.
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]+)(?:/(.+))?/?$ /?p=$1&$2 [QSA,L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby deamon » Thu Mar 26, 2009 3:55 am

richardk wrote:/index/id=234 or /index/?id=234?

Try
Code: Select all
Options +FolowSymLinks

RewriteEngine On

# Ignore existing files.
RewriteCond %{SCRIPT_FILENAME} !-f
# Ignore existing directories.
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^/]+)(?:/(.+))?/?$ /?p=$1&$2 [QSA,L]


I got the 500 error when trying this. I tried all the combination of pages and all I get is the 500 Error. Without the first "?" would be the correct choice. Thanks for your help!

Edit: There was a typo in +FollowSymLinks :P. Now another problem occurs. When I have a folder: http://host/folder/index it still detects "folder" as being the value of the parameter "p". So I guess apache sees "http://host/?p=folder/index. I found that out while echoing $_GET['p']. Other than that, it works perfectly for the root folder.

Thanks again.
deamon
 
Posts: 16
Joined: Thu Jul 20, 2006 9:13 pm

Postby richardk » Thu Mar 26, 2009 9:39 am

Now another problem occurs. When I have a folder: http://host/folder/index it still detects "folder" as being the value of the parameter "p". So I guess apache sees "http://host/?p=folder/index.

Is folder an existing directory?
What should happen?
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby deamon » Thu Mar 26, 2009 10:06 am

Yes, "folder" is an existing directory. The page works fine but it seems ?p= as being "folder" instead of parameter #2.

http://host/index : http://host/?p=index (works)

http://host/folder/index : http://host/folder/index (doesn't work, seems "folder" as being parameter to ?p

So basically, the logic should be, if is not in existing dir (root), then parameter 1 should be "p", if it's in an existing directory, second parameter should be "p".
deamon
 
Posts: 16
Joined: Thu Jul 20, 2006 9:13 pm

Postby richardk » Thu Mar 26, 2009 10:38 am

I can't think of a good way to do it.
Code: Select all
Options +FollowSymLinks

RewriteEngine On

# 4 directories deep.
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1/ -d
RewriteRule ^(([^/]+/){3}([^/]+))(/(.+))?/?$ /?p=$3&$5 [QSA,L]

# 3 directories deep.
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1/ -d
RewriteRule ^(([^/]+/){2}([^/]+))(/(.+))?/?$ /?p=$3&$5 [QSA,L]

# 2 directories deep.
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1/ -d
RewriteRule ^([^/]+/([^/]+))(/(.+))?/?$ /?p=$3&$5 [QSA,L]

# 1 directories deep.
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1/ !-d
RewriteRule ^([^/]+)(/(.+))?/?$ /?p=$1&$3 [QSA,L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby deamon » Thu Mar 26, 2009 11:08 am

It didn't work. There will always be a maximum of 1 existing directory deep. I'll try to help you out here the best I can.

Here's my folder hierarchy:

Code: Select all
/
/pages/
/folder1/
/folder2/
/folder3/
/index.php


Alright, so index.php has a p parameter eg. /index.php?p=users (in root). The "p" parameter goes fetch the /pages/ folder which is always at root. Now, here I have 3 sub application: folder1, folder2, folder3. All of those have the same function as the root: /folder1/index.php?p=users which will go fetch the page "users" in the /pages/ directory which will always be at root. All of the pages are the same, all the sub applications users the same /pages/ folder which is in the root directory.

Now, instead of having: http://host/folder1/?p=users&whatever=otherparam, it would be http://host/folder/users/whatever=otherparam. The same principal goes for root: http://host/users/whatever=otherparam. The "catch" here is that there might be a directory, or not.

Note, will always be 1 directory deep.

Thanks for your help richardk.

Edit: I forgot to mention the error I get. Again, in root it works good. Now when I access a page: http://host/subapp1/index, there's a 404 saying the folder /subap1/index cannot be found.
deamon
 
Posts: 16
Joined: Thu Jul 20, 2006 9:13 pm

Postby richardk » Fri Mar 27, 2009 2:05 am

Try
Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteRule ^(.+/)?([^/]+)/([^/]*(=&)[^/]*)$ /$1?p=$2&$3 [L]

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.+/)?([^/]+)/?$ /$1?p=$2 [L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby deamon » Tue Apr 21, 2009 9:13 am

richardk wrote:Try
Code: Select all
Options +FollowSymLinks

RewriteEngine On

RewriteRule ^(.+/)?([^/]+)/([^/]*(=&)[^/]*)$ /$1?p=$2&$3 [L]

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.+/)?([^/]+)/?$ /$1?p=$2 [L]


Thanks Richard! It works perfectly except for:

http://host/app1/page1/id=123

but adding "?" will work:
http://host/app1/page1/?id=123

so it's no big deal, thanks again!
deamon
 
Posts: 16
Joined: Thu Jul 20, 2006 9:13 pm

Postby richardk » Tue Apr 21, 2009 9:46 am

Try replacing
Code: Select all
(=&)

with
Code: Select all
(=|&)
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Next

Return to Friendly URLs with Mod_Rewrite

Who is online

Users browsing this forum: Majestic-12 [Bot] and 21 guests

cron