homepage Welcome to WebmasterWorld Guest from 54.226.161.112
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Subscribe to WebmasterWorld
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Help needed: Rewrite with more than 10 parameters
Rewrite with more than 10 parameters
jiby




msg:3452046
 3:55 am on Sep 16, 2007 (gmt 0)

Hi, gang. I'm trying to rewrite urls having optional parameters and multiple variable, of this type:


http:// www.mysite.com/index.php?j1=1&j2=2&j4=4&j5=5&j7=7...
http:// www.mysite.com/index.php?j2=2&j3=3&j3=3&j5=5&j6=6&j7=7...

The URL I want to show in browser is:
http:// www.mysite.com/keyword/j1_1/j2_2/j3_3/j4_4/j5_5/j6_6/j7_7/...

Obviously, with this many parameters I would eventually pass the limit of 9 mod_rewrite variables. So I was trying to "replace" strings inside URL. The rewrite code I came up with is:


RewriteRule ^keyword([^/]+)?(/j1_([^/]+))?(.*)$ keyword$1&j1=$2$3 [nc]
RewriteRule ^keyword([^/]+)?(/j2_([^/]+))?(.*)$ keyword$1&j2=$2$3 [nc]
RewriteRule ^keyword([^/]+)?(/j3_([^/]+))?(.*)$ keyword$1&j3=$2$3 [nc]
RewriteRule ^keyword([^/]+)?(/j4_([^/]+))?(.*)$ keyword$1&j4=$2$3 [nc]
RewriteRule ^keyword([^/]+)?(/j5_([^/]+))?(.*)$ keyword$1&j5=$2$3 [nc]
RewriteRule ^keyword([^/]+)?(/j6_([^/]+))?(.*)$ keyword$1&j6=$2$3 [nc]
RewriteRule ^keyword([^/]+)?(/j7_([^/]+))?(.*)$ keyword$1&j7=$2$3 [nc]
RewriteRule ^keyword([^/]+)? index.php?$1 [nc,l]

No 404 or 500 error after implementing this above, but unfortunatelly there were no values for the variables in the rewritten URL:
http:// www.mysite.com/index.php?&j1=&j2=&j3=&j4=&j5=&j6=&j7=...

If anyone figures out where the error is in the code, please help me out. Many thanks in advanced!

 

jdMorgan




msg:3452271
 3:09 pm on Sep 16, 2007 (gmt 0)

One thing that may help you debug this is to change the rule to an external redirect so you can see what is going on.

Obvious problems are a missing slash and the use of $2, which contains the entire optional parameter on each line, e.g. "j1_124", when all you want is $3 which contains only "124".

However, you may be running into a well-known Apache mod_rewrite bug [searchengineworld.com] that crops up when a URL-path is rewritten repeatedly. The result is that duplicate URL info is appended to the URL-path, which to use highly-technical terminology, "really messes things up."

As a result, I'd suggest an alternate approach, using the "user-defined variable" method:

# Skip following section if not a "keyword/" request
RewriteRule !^keyword/ - [S=9]
#
# Else copy/append keywords to user-defined variable "tQuery"
RewriteRule ^keyword(/[^/]+)*/j1_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}j1=$2]
RewriteRule ^keyword(/[^/]+)*/j2_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j2=$2]
RewriteRule ^keyword(/[^/]+)*/j3_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j3=$2]
RewriteRule ^keyword(/[^/]+)*/j4_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j4=$2]
RewriteRule ^keyword(/[^/]+)*/j5_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j5=$2]
RewriteRule ^keyword(/[^/]+)*/j6_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j6=$2]
RewriteRule ^keyword(/[^/]+)*/j7_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j7=$2]
#
# Strip leading "&" from tQuery (if any)
RewriteCond %{ENV:tQuery} ^&(.+)$
RewriteRule ^keyword/ - [NC,E=tQuery:%1]
#
# Rewrite the URL-path to index.php query format
# RewriteRule ^keyword/ /index.php?%{ENV:tQuery} [NC,L]
#
# Use the following rule for easier testing only, then un-comment the rule above and delete this one.
RewriteRule ^keyword/ http://example.com/index.php?%{ENV:tQuery} [NC,R=301,L]

Here, we leave the requested URL-path entirely unchanged while appending each keyword-path value onto a temporary query string variable "tQuery". Then at the end, we use the built-up tQuery variable as the new query string.

The first rule is for efficiency only. It is entirely optional, but intended to improve performance if you add many more query parameters. It simply skips all the rules in this set if the URL does not start with "keyword/"

I sure hope I typed everything correctly and didn't forget anything!

Jim

and1c




msg:3452338
 5:09 pm on Sep 16, 2007 (gmt 0)

That is a great contribution there Jim!
Nice work!

jiby




msg:3452511
 4:24 am on Sep 17, 2007 (gmt 0)

Thanks a lot, Jim! It worked very well from the first try. I was even able to tweak your code a bit, so that it accepts City Names within the "keyword", something like "keyword_Chicago/...". My final code is:


# Copy/append keywords to user-defined variable "tQuery"
# First rule is to accept CityName inside "keyword" term, like "keyword_Chicago"
RewriteRule ^keyword(_[^/]+)*_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&cityname=$2]
# The other rules are for other optional parameters
RewriteRule ^keyword(_[^/]+)?(/[^/]+)*/j2_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j2=$3]
RewriteRule ^keyword(_[^/]+)?(/[^/]+)*/j3_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j3=$3]
RewriteRule ^keyword(_[^/]+)?(/[^/]+)*/j4_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j4=$3]
RewriteRule ^keyword(_[^/]+)?(/[^/]+)*/j5_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j5=$3]
RewriteRule ^keyword(_[^/]+)?(/[^/]+)*/j6_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j6=$3]
RewriteRule ^keyword(_[^/]+)?(/[^/]+)*/j7_([^/]+) - [NC,E=tQuery:%{ENV:tQuery}&j7=$3]
# Strip leading "&" from tQuery (if any)
RewriteCond %{ENV:tQuery} ^&(.+)$
# Tweaked to look for city name (if any)
RewriteRule ^keyword(_[^/]+)?(/)? - [NC,E=tQuery:%1]
# Rewrite the URL-path to index.php query format
# Tweaked to look for city name (if any)
RewriteRule ^keyword(_[^/]+)?(/)? /index.php?%{ENV:tQuery} [NC,L]

With this code visitors can follow URLs with optional parameters, like:
http://www.example.com/keyword_Chicago/j1_param/j2_param/j3_param/...
or just:
http://www.example.com/keyword/j2_param/j3_param/...

Thanks again, Jim!

jdMorgan




msg:3452708
 1:03 pm on Sep 17, 2007 (gmt 0)

Since this is the first use of tQuery, you don't need the leading "&" and you don't need to refer to the previous tQuery value:

RewriteRule ^keyword(_[^/]+)*_([^/]+) - [NC,E=tQuery:}cityname=$2]

It is not necessary to enclose optional single characters in parentheses to quantify them:

# Tweaked to look for city name (if any)
RewriteRule ^keyword(_[^/]+)?[b]/?[/b] - [NC,E=tQuery:%1]
# Rewrite the URL-path to index.php query format
# Tweaked to look for city name (if any)
RewriteRule ^keyword(_[^/]+)?[/b]/?[/b] /index.php?%{ENV:tQuery} [NC,L]

And actually, since the patterns are not end-anchored and the first sub-pattern is lookinf for "not a slash", you don't need to check for the trailing slash at all:

# Tweaked to look for city name (if any)
RewriteRule ^keyword(_[^/]+)? - [NC,E=tQuery:%1]
# Rewrite the URL-path to index.php query format
# Tweaked to look for city name (if any)
RewriteRule ^keyword(_[^/]+)? /index.php?%{ENV:tQuery} [NC,L]

And are you sure you really want to replace all parameters and throw away all the other parameters in the first of these two rules? (I really don't understand what this first rule is intended to do, since you already captured cityname in the first rule of your whole code segment.

Jim

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved