Welcome to WebmasterWorld Guest from 54.205.170.21

Forum Moderators: Ocean10000 & incrediBILL & phranque

Message Too Old, No Replies

Help needed: Rewrite with more than 10 parameters

Rewrite with more than 10 parameters

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

5+ Year Member



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!

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

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member



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

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

5+ Year Member



That is a great contribution there Jim!
Nice work!
4:24 am on Sep 17, 2007 (gmt 0)

5+ Year Member



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!

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

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member



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

 

Featured Threads

Hot Threads This Week

Hot Threads This Month