Redirecting with very similar URLs

I’ve been asked to put some redirects in place on our server that will forward all of these to one location:

These should all go to domain.com/category/item.html however everything I try seems to end up in an infinite loop. Please help!

This is what I have so far:

Options +FollowSymlinks
RewriteEngine On

RewriteCond %{HTTP_HOST} !^www\\.domin\\.com
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^category/item?$ /category/item.html [L,R=301]
RewriteRule ^category/trafalgar/?$ /category/item.html [L,R=301]
RewriteRule ^category/trafalgar.html/?$ /category/item.html [L,R=301]
RewriteRule ^item?$ /category/item.html [L,R=301]
RewriteRule ^item/?$ /category/item.html [L,R=301]
RewriteRule ^item.html?$ /category/item.html[L,R=301]
RewriteRule ^item.html/?$ /category/item.html [L,R=301]

The 301s are actually 302s in my tests so I don’t permanently send myself to the wrong place. The problem appears to be that item always matches, irrespective of whether category preceeds it or not. I’m not entirely sure how to deal with that as it’s never been a requirement before.

Any help please?

[font=verdana]I think (and I’m not an htaccess expert, but I like a challenge!) the problem is with your use of the question mark.

Taken from http://www.yourhtmlsource.com/sitemanagement/urlrewriting.html:

The question mark means ‘zero or one of the preceding character or range’

where (from their examples), the preceding character or range seems to be defined by being in brackets. I’m guessing that without brackets, it takes everything into account, so will be a universal match. If I’ve guessed right, what you actually want, instead of

[COLOR="#dd0000"]RewriteRule ^item?$ /category/item.html [L,R=301]
RewriteRule ^item/?$ /category/item.html [L,R=301][/COLOR]

is

[COLOR="#008000"]RewriteRule ^item(/)?$ /category/item.html [L,R=301][/COLOR]

But I freely admit that is off the top of my head, and take no responsibility for any catastrophes that may ensue if you just copy and paste this without testing it…[/font]

Stevie,

Good try! The ? in regex is “zero or one of the preceding character” but the square brackets you referenced could specify the character as being in an allowable set, i.e., it has nothing to do with grouping. Your use of the parenthetical does group and, if followed by a ? will make the entire group optional.

Antnee,

Redirect (almost) everything to one location, eh? Why not:

RewriteEngine on

RewriteRule ^(category/)?item(/|\\.html/)?$ category/item.html [R=301,L]

Okay, that looks a bit complex but it says:

Start with an optional category/, continue with item, continue with EITHER an optional trailing / OR .html/ and ends. The redirection will not loop as category/item.html does not have a trailing /.

WARNING, a redirection like this (many different levels of directories for your request) will force the use of (internal) absolute links in all support files (.css, .js, .gif, .jpg, etc.) and, IMHO, a trailing / is something which is ONLY done for a directory request.

Regards

DK

Feeling a bit daft actually. I knew that about the ? but I still put it in my example, though admittedly I was trying it with and without and it just happened that I had it in at the time. Even so, pointless! :smiley:

@dklynn I tried your example and had to make a slight change to make the redirected URL the full URL:

RewriteRule ^(category/)?item(/|\\.html/)?$ http://www.domain.com/category/item.html [R=301,L]

That did the job perfectly and also got around another problem I was having further down where another part of the rewrites were appending query string data to the URL so it was becoming:

http://www.domain.com/category/item.html?url=item

Thank you very much :slight_smile:

Oh no, it hasn’t worked after all… I hadn’t realised but it only redirects from these:

  • item
  • item/
  • item.html/
  • category/item
  • category/item/
  • category/item.html/

I also need it to redirect from item.html but then it ends up in an infinite loop again because it still sees item.html in the final path:

RewriteRule ^(category/)?item(/|\\.html/|\\.html)?$ http://www.domain.com/category/item.html [R=301,L]

This seems to work:

RewriteRule ^category/item(/|\\.html/)?$ http://www.domain.com/category/item.html [R=301,L]
RewriteRule ^(?!category/)item(/|\\.html/|\\.html)?$ http://www.domain.com/category/item.html [R=301,L]

Not the pretiest, admittedly, but I can’t work out any other way of doing it :confused:

Er … huh? The only square brackets that I refered to or featured in my post were the control codes (I don’t know if there’s a more technical name for them than that) at the end of the lines…

Stevie,

What square bracket comment? It must have been in another thread but it was not aimed at you; it referred to that OP’s attempting to match Google’s encoding of the ?, = and & characters within regex expressions.

Antnee,

You specified the series of item, item/, item.html/, category/item, category/item/ and category/item.html/ so that’s EXACTLY what you got! Okay, okay, a change in specification brings:

RewriteEngine on

RewriteRule ^(item\\.html|(category/)?item(/|\\.html/))?$ category/item.html [R=301,L]

Regards,

DK

@dklynn thanks for the updated rule, that’s brilliant. I haven’t changed my specification mind you (counted them to make sure I’m not going mad :D)

All this assistance is greatly appreciated

Antnee,

Wait while I take off my shoes … aw, you’re too right! I hadn’t considered that case in the logic. 'Glad it’s working for you now.

Regards,

DK