Forum Moderators: phranque

Message Too Old, No Replies

HTACCESS question

need help redirecting part of a query string

         

ythefnot

5:36 pm on Jul 7, 2015 (gmt 0)

10+ Year Member



Hi. In the process of consolidating pages (four into one), so I'd like to alter our htaccess file so that the following:

foo.com/?product=product-name-goes-here&page=benefits
foo.com/?product=product-name-goes-here&page=features
foo.com/?product=product-name-goes-here&page=documents

all redirect to
foo.com/?product=product-name-goes-here&page=overview

I'd like it to be flexible as possible so that one command will handle all the "product-name-goes-here" products.

I've tried multiple different rewriterules, but nothing seems to work...

Thanks in advance for you help!

bw

ythefnot

6:05 pm on Jul 7, 2015 (gmt 0)

10+ Year Member



oh, one last thing: the foo.com/?product=product-name-goes-here&page=overview page already exists, so I don't want anything that's going to "infinite loop" on me...

whitespace

6:39 pm on Jul 7, 2015 (gmt 0)

10+ Year Member Top Contributors Of The Month



What have you tried so far?

ythefnot

6:45 pm on Jul 7, 2015 (gmt 0)

10+ Year Member



Options +FollowSymlinks
RewriteEngine On
RewriteCond %{QUERY_STRING} product=(.+)
RewriteRule ^?product=([^/]+)&page=benefits ?product=$1&page=overview [QSA]
RewriteRule ^?product=([^/]+)&page=features ?product=$1&page=overview [QSA]
RewriteRule ^?product=([^/]+)&page=documents ?product=$1&page=overview [QSA]

and

RewriteRule ^(.*)product(.*)benefits(.*)$ $1product=$2overview [L,R=301]
RewriteRule ^(.*)product(.*)features(.*)$ $1product=$2overview [L,R=301]
RewriteRule ^(.*)product(.*)documents(.*)$ $1product=$2overview [L,R=301]

lucy24

6:48 pm on Jul 7, 2015 (gmt 0)

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



Edit:
Oops, sorry whitespace, that will teach me to keep multiple tabs open without refreshing ;)

I've tried multiple different rewriterules, but nothing seems to work...

OK, let's see 'em. And when you say "doesn't work" do you mean that the rule doesn't appear to execute at all, or do you mean something else? ("Correct RewriteRules are all alike. Incorrect RewriteRules are all incorrect in their own way." --Tolstoy, I think, but don't quote me.)

the foo.com/?product=product-name-goes-here&page=overview page already exists

That shouldn't make any difference, since you're changing the value of the parameter, and only redirecting certain old values.

:: insert boilerplate about possibility of changing to friendly URLs as long as you're in there making changes anyway ::

Further edit:
Quick detour to test site confirms that this
RewriteRule ^? blahblah
is a 500-class error. Did something get lost in the copy-and-paste?

ythefnot

7:03 pm on Jul 7, 2015 (gmt 0)

10+ Year Member



nope... I certanily got a 500-class error!

lucy24

8:45 pm on Jul 7, 2015 (gmt 0)

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



The sequence ^? creates a 500-class error because it's an invalid Regular Expression. The ^ is an opening anchor meaning "the following content has to come at the very beginning of the test string"; the ? means that the immediately preceding element, whatever it may be (single character, or bracketed group, or package in parentheses), is optional. What you meant to say is probably ^\? meaning a literal question mark coming immediately after the root. But the rule would still fail, because a question mark introduces a query string, while a RewriteRule can only look at the path. So what you "really" meant was
RewriteCond %{QUERY STRING} patternblahblah
RewriteRule ^(index\.\w+)?$ targetblahblah%1blahblah
But before we can hammer out the exact form of the "patternblahblah", we need to work out in english what all possible inputs are.

It looks as if you want to keep one part of the query while changing another part. Is there any possibility that it would ever be in the form
page=something&product=something-else
? Even if your code is set up so things always come in the same order, you have to allow for type-ins and possibly search engines.

Digression: I don't know whether search engines will intentionally ask for parameters in the "wrong" order. I do know that they will intentionally ask for "index.html" to see whether they get redirected* even if none of your URLs has ever said "index.html". (For deeper directories, they will also ask for the same URL minus the trailing slash. This isn't an issue for the front page.) Rules have to cover all possibilities. That's why I said (index\.\w+)? up above. It covers index.html, which I know they will ask for, and index.php, which they might ask for. All this is because it isn't enough to redirect humans; you also need to redirect search engines. If you don't know for sure, have a look at a few days of server access logs and see if anyone like the Googlebot or bingbot has ever requested an URL with parameters in the wrong order.

Will the first part of the query string-- the "product=blahblah" part-- have a variety of different values that you need to preserve? I'm guessing yes. And does the second part-- the "page=blahblah" part-- have other values that will not get redirected? Or are you redirecting all possible values of "page" to a single value? (In which case, why keep the parameter at all?)

Belated question: Is this all happening in some standard CMS, or do you roll your own PHP? It might be simpler to put the redirecting part into the php itself, either as part of the script that builds the page, or as a separate "fixup.php" detour.

Are there other changes happening on the site, or is it just this four-into-one collapse?


* Otherwise known as Entrapment.

ythefnot

8:59 pm on Jul 7, 2015 (gmt 0)

10+ Year Member



The answers, in no particular order:

CMS is roll-our-own

This is the only four-into-one collapse

our infrastructure doesn't call for an index file, the url goes straight from the first slash to the question mark that begins the query string

order of parameters is always going to be foo.com/?product=[a value that will change, but we will want to capture]&page=[either overview, benefits, features or documents] (at least as far as links to and within the site are concerned... there's not much we can do about folks hand-jamming text into the location box on the browser...)

we want all "product" traffic to go to the particular product's overview "page"

thanks in advance for your help on this...

lucy24

6:17 am on Jul 8, 2015 (gmt 0)

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



I couldn't quite understand why the "page=" parameter needs to be retained at all, if its value is always going to be "overview". Wouldn't it be simpler just to dump it, hard-code the "overview" value into the php, and redirect any incoming requests that specify a "page"?

If you did it in php, it would be straightforward, because you could pull each parameter separately, regardless of order

:: looking vaguely around for whitespace, who was here a minute ago ::

Conceptually it's:
IF {value of "page" != "overview"}
THEN {issue an immediate 301 redirect to "page=overview" and "product=whatever-it-already-was"}
ELSE {proceed to whatever page-building stuff the php would normally do at this point}

In mod_rewrite it's a little more complicated because there are at least two possible permutations (more, if there are more than two potential parameters). One possibility:
RewriteCond %{QUERY_STRING} ^(product=[^&]*)&page=(?:benefits|features|documents)
RewriteRule ^(index\.\w+)?$ http://www.example.com/?%1&page=overview [R=301,L]

RewriteCond %{QUERY_STRING} ^page=(?:benefits|features|documents)&(product=.*)
RewriteRule ^(index\.\w+)?$ http://www.example.com/?%1&page=overview [R=301,L]
Note that with ?: for non-capturing group, the two rules are identical; only the condition looking at the query string is different.

Another:
RewriteCond %{QUERY_STRING} !page=overview(&|$)
RewriteCond %{QUERY_STRING} (product=[^&]*)
RewriteRule ^(index\.\w+)?$ http://www.example.com/?%1&page=overview [R=301,L]
This version means "if the 'page' parameter is absent entirely, or its value is anything other than the exact string 'overview'".

In every case, the capture has to occur in the last condition (the one immediately before the rule) if there's more than one.

ythefnot

3:24 pm on Jul 9, 2015 (gmt 0)

10+ Year Member



wow... that last one worked perfectly...

thanks so much!