Forum Moderators: phranque

Message Too Old, No Replies

Two variable URL rewrite

need to assign second variable if not passed

         

StoutFiles

3:42 am on Oct 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Current redirects are as followed.

Options +FollowSymLinks
RewriteEngine on

//non-www to www
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

//one-variable
RewriteRule ^widgets/([^/]+) /widgets.php?widget=$1 [NC]

//two-variable
RewriteRule ^cogs/([^/]+)/([^/]+) /cogs.php?type=$1&color=$2 [NC]

The two-variable works but I what I need is if "color" isn't defined to be able to assign it a default value...I've seen other sites do this.

Example:
www.example.com/big/red stays as www.example.com/big/red
www.example.com/big/ goes to www.example.com/big/red

jdMorgan

4:14 am on Oct 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Your patterns aren't end-anchored, and this can cause you trouble with adding 'default' support, so we need to take care of that up-front.

Assuming that the URL ends right after "/red" or has a trailing slash, as in "/red/", then change the internal rewrites as follows:


# one-variable
RewriteRule ^widgets/([^/]+)/?$ /widgets.php?widget=$1 [NC,L]
#
# two-variable
RewriteRule ^cogs/([^/]+)/([^/]+)/?$ /cogs.php?type=$1&color=$2 [NC,L]
#
# two-variable with default color
RewriteRule ^cogs/([^/]+)/?$ /cogs.php?type=$1&color=red [NC,L]

Note the end-anchored patterns and the use of [L] in all cases (unless *you* know why you don't want to use it).

You should review your URL-plan and the rules above. If your URLs have no trailing slash, then remove the "/?" from the (now) last three rules. If your URLs always have a trailing slash, then remove only the "?".

If you actually need the [NC] flag for these rules to function, then find out who's linking to you with uppercase characters and ask them to stop.

Then go back and add external redirects to force all lowercase URLs or let them go 404.

You need to remove the [NC] flag from these last three rules. Right now, with slash and no-slash and any-case widgets and cogs, you've got an astronomical number of duplicate-content URL possibilities, and this is an exploitable vulnerability.

Jim

StoutFiles

5:25 am on Oct 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You should review your URL-plan and the rules above. If your URLs have no trailing slash, then remove the "/?" from the (now) last three rules. If your URLs always have a trailing slash, then remove only the "?".

Is there a way to have the slash and have non-slash URL's add the slash? I don't want to 404 if the slash is forgotten, but I'd prefer to always have it.

Also have this in my .htaccess as well.
RewriteRule ^([^.]*)/$ $1.php [l]

g1smd

10:49 am on Oct 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, add a redirect for that and add it as the very first rule - even before your non-www to www redirect rule.

The new rule must state the domain name in the target URL so as to avoid a chained redirect for non-www URL requests that are also missing the slash.

There's a problem with your non-www to www URL redirect. It currently says "Redirect to www if the request does not begin www.example.com". That means a request for www.example.com:80 will not be redirected because it does begin with a www. However the :80 version is a duplicate URL. Add a closing $ to the existing condition so that instead it becomes "Redirect to www if the request is not exactly www.example.com".

jdMorgan

4:47 pm on Oct 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



... and remove the [NC] to avoid duplicates on mis-cased requests as well.

Jim

mjoh090

9:55 pm on Oct 20, 2009 (gmt 0)

10+ Year Member



Is it possible to attack this problem from the definition of the RewriteCond? Is it possible to construct a RewriteCond with the scope to cover a variable in a dynamic url when it has null value.

My problem is very similar that I may be approaching from the wrong angle.

The Problem:

The dynamic url has 15 variables each of which may or may not have a value. For design reasons, even when a variable is null, it is still parsed with the url. I wish to rewrite this dynamic url into a static url. The problem I am encountering is that the RewriteCond that I am using to define the form of the url, does not recognise the form as a match when the variable is null. eg

When the url is mydomain.com/search.php?one=A&two=B... the following works (placed in httpd.conf):

RewriteRule ^/search/([^&]+)/([^&]+)/? /search.php?one=$1&two=$2
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /search\.php\?one=([^&]+)&two=([^&]+)
RewriteRule ^/search\.php$ htp://{HTTP_HOST}/search/$1/$2? [301,L]

But when the url is mydomain.com/search.php?one=&two=B... the above condition no longer works. The RewriteCond that works is:

RewriteRule ^/search/([^&]+)/? /search.php?one=&two=$1
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /search\.php\?one=&two=([^&]+)
RewriteRule ^/search\.php$ htp://{HTTP_HOST}/search/$1? [301,L]

My question is:

Is it possible to construct a single RewriteCond that covers the scope of both RewriteConds above? If so, how?

Many Thanks,

Mark

mjoh090

10:00 pm on Oct 20, 2009 (gmt 0)

10+ Year Member



Errata:
The first Rewrite rules above additionally have the [PT] tag.

RewriteRule ^/search/([^&]+)/([^&]+)/? /search.php?one=$1&two=$2 [PT]

RewriteRule ^/search/([^&]+)/? /search.php?one=&two=$1 [PT]

jdMorgan

12:18 am on Oct 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



"([^&]+)" requires at least one (or more) non-ampersand character.
"([^&]*)" allows zero or more non-ampersand character.

Changing the RewriteCond pattern from the former to the latter would allow for a blank value.

I'd suggest stopping for now and reviewing regular expressions quantifiers...

Also, an SEO comment: 15 variables is too many. Like King Leopold told the young Mozart, "Take a few out." You're stuck between a non-indexable query-string URL and a super-spammy-looking apparently-static URL, and neither is "SEO friendly." Therefore, this project may need to change from a simple query-string-to-URL-path transliteration into more of a "URL-space redesign"... if that's possible.

Jim

mjoh090

12:38 am on Oct 21, 2009 (gmt 0)

10+ Year Member



Fantastic. This is exactly what I needed. Thank you very much.