Forum Moderators: phranque

Message Too Old, No Replies

Selective htaccess redirect

         

onetry

7:52 am on Jun 15, 2011 (gmt 0)

10+ Year Member



Hi,

I need to write some 301 redirect rules to achieve the following behavior:

All pages from www.old-domain.com must redirect to a new URL with this schema:

www.old-domain.com/<part_of_url> --> www.newdomain/yyyy/mm/<part_of_url>

Additionally, the "en" version has to follow same rules:

www.old-domain.com/en/<part_of_url> --> www.newdomain/en/yyyy/mm/<part_of_url>

and the "de" version has to do nothing!

www.old-domain.com/de/<part_of_url> --> browse normally the URL without redirect.

Just to add complexity, this rules have to integrate themselves with wordpress ones.

Is it possible ?

Thanks for help!

lucy24

6:12 pm on Jun 15, 2011 (gmt 0)

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



Do you mean that the /de/ version is staying in the old domain while you're spinning-off the forms with /en/ or nothing? Will it keep the /de/? Please say yes, or you risk going into perpetual motion.

Either way, your magic words will be
!^/de

meaning that this version will be excluded from any other rewriting or redirecting activity. Important detail! Do any of your "the rest of the url" elements happen to begin with the letters "de"? If so, you have to be a little more careful in writing the "does not begin with" part so you don't accidentally exclude them.

It helps that the /en/, if present, comes before the other stuff you're capturing, because RegExes are greedy by default. So if you say
(/en)?(/the rest of the stuff)
the first piece will be captured separately if present. And then you simply go to
www.newdomain$1/yyyy/mm$2
where it doesn't matter if $1 happens to be empty.

But if you had
(/the rest of the stuff)(/en)?
the /en would be swallowed up in the first part of the capture unless you made the whole thing a lot more complicated.

onetry

7:27 am on Jun 16, 2011 (gmt 0)

10+ Year Member



Hi Lucy thanks for reply.

Yes, www.old-domain.com/de/<the rest of the stuff> will stay in the old domain and anything else will redirect, using above schema, to the new domain.


(/en)?(/the rest of the stuff)
the first piece will be captured separately if present. And then you simply go to
www.newdomain$1/yyyy/mm$2


yyyy --> can change, it represents the year
mm --> can change, it represents the month

Lucy, I am a total newbie in mod_rewrite, I will appreciate so much if you can help me writing all rules to insert in my .htaccess.

Best regards :D

g1smd

8:03 pm on Jun 16, 2011 (gmt 0)

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



There is no way for mod_rewrite to add the /yyyy/ and /mm/ information in the redirect, unless that data was already present in the original request.

lucy24

11:06 pm on Jun 16, 2011 (gmt 0)

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



Oops. Sorry. yyyy/mm wasn't just a random string of letters. Ahem.

You've got two options. Either run it by an outside code such as php that can fill in the year and month for you, or change it by hand. Are the y and m based on the date right now, or on some other variable? If it's the real-life current date, then changing it manually once a month may be less trouble than any alternative ;)

onetry

2:03 pm on Jun 17, 2011 (gmt 0)

10+ Year Member



Ok Lucy, got it.

Can you please help me then to achieve this:

www.olddomain.com/<whatever> --> www.newdomain.com
www.olddomain.com/en/<whatever> --> www.newdomain.com/en
www.olddomain.com/de/<whatever> --> no action

I tried but failed because first rule always override other 2 ...

Thanks :)

onetry

2:04 pm on Jun 17, 2011 (gmt 0)

10+ Year Member



@g1smd:

no way to say "%%%%/%%" like jolly character in SQL ?

thanks !

lucy24

6:35 pm on Jun 17, 2011 (gmt 0)

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



You need to go from more specific to less specific. So you first do

www.olddomain.com/en/<whatever> --> www.newdomain.com/en/ [R=301,L]

The [L] is vital here because it means "don't do any more rewriting even if you find another rule that fits".

And then do (this is not meant as a direct cut & paste!)

RewriteCond !^www.olddomain.com/de/
RewriteRule www.olddomain.com www.newdomain.com

meaning "anything that doesn't start like this". If you hadn't used the [L] in the previous rewrite, the /en/ would get rewritten all over again, because newdomain obviously doesn't match olddomain.

And you don't need to say anything about /de/ at all because you're not doing anything to it ;)

onetry

6:57 am on Jun 20, 2011 (gmt 0)

10+ Year Member



lucy24, thanks.

However I can't make the "de" exclusion work.

I wrote that into htaccess:


RewriteRule ^en/(.*)$ [newsite...] [R=301,L] # WORKS!
RewriteCond %{REQUEST_URI} !^/(de|de/.*)$ # DOES NOT WORK :(
RewriteRule ^(.*) [newsite.com...] [R=301,L] # WORKS!

Please note that "de" is NOT a real directory and it is only the URL that is rewritten below from other Wordpress rules.

Any help appreciated.

Regards.

g1smd

8:58 am on Jun 20, 2011 (gmt 0)

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



It matters not if "de" is a real directory or not.

Mod_rewrite deals with URL requests. It examines the literal "
GET /something HTTP/1.1
" request sent by the browser or bot. In order for the rule to work, a browser or bot must have made a request for a URL with /de/ in it (or made a request without /de/ in it).

The target of the RewriteRule must be either another URL (that the browser will make a new request for, after the external redirect) or an internal server filepath and file (served silently by the server, using an internal rewrite).

lucy24

3:24 pm on Jun 20, 2011 (gmt 0)

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



Oh, wait.
RewriteCond %{REQUEST_URI} !^/(de|de/.*)$ # DOES NOT WORK

I don't think you need the anchors at all, unless you've gone and used /de/ elsewhere in addresses. (Please say you haven't.) I think all you need is

!/de/

meaning "exclude anything that contains this piece anywhere".

g1smd

4:57 pm on Jun 20, 2011 (gmt 0)

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



I thought that at first, but look again.

The pattern matches:
exactly
/de

exactly
/de/

and
/de/anything

while NOT matching /destination or other words beginning with /de.

onetry

5:10 pm on Jun 20, 2011 (gmt 0)

10+ Year Member



@lucy24:
# is not anchor ... is remark symbol after which I comment something only on forum :)
However I tried also: RewriteCond %{REQUEST_URI} !^/(de) but it does not work :(
Is rewritecond position correct, related to rewrite rule ?

@g1smd:
what you are describing (The pattern matches:) is exactly what I an looking for.
Please can you support me why it does not work ?

I would to thanks both for support !

lucy24

9:22 pm on Jun 20, 2011 (gmt 0)

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



! light bulb !

Are you allowed to use pipes with ! or does that break in the same way as ! with a too-vague class? That is, does
!^/(de|de/.*)$

mean "NEITHER /de exactly NOR /de/maybe more here" or does it mean "EITHER not /de exactly OR not /de/maybe more here"?

Try making your condition into two lines (with implied "and")
RewriteCond %{REQUEST_URI} !^/de$
RewriteCond %{REQUEST_URI} !^/de/
(trimming this because .*$ is the same as not saying anything at all)

g1smd

10:19 pm on Jun 20, 2011 (gmt 0)

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



The original pattern was correct and functionally equivalent.

It redirects only a word beginning /de but does not redirect anything found in the list in my post further up the page.

lucy24

10:36 pm on Jun 20, 2011 (gmt 0)

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



The original pattern was correct and functionally equivalent.

Well, that was my question. So the pipes in conjunction with ! do come out meaning "NEITHER a NOR b" as intended, rather than "EITHER NOT a OR NOT b" as very much not intended. Running out of straws to grasp at...

Is rewritecond position correct, related to rewrite rule ?

Each RewriteRule is preceded by zero or more RewriteCond. As soon as you pass a Rule, the Conditions disappear and you have to start over again. So if you have

RewriteRule ...
RewriteCond ...
RewriteRule ...

It means: apply the first rule to any request that fits into the rule. Apply the second rule to any request that fits into the rule and also meets the condition in the previous line.

Onetry, are you starting to have second thoughts about your handle? :)

onetry

2:01 pm on Jun 22, 2011 (gmt 0)

10+ Year Member



Unfortunately it does not work.

The only way I found to make it almost work is:

RewriteRule ^en/(.*)$ [newsite.com...] [R=301,L]
RewriteCond %{THE_REQUEST} !^[A-Z]+\ /de/
RewriteRule ^(.*) [newsite.com...] [R=301,L]

The only problem is that when I surf:

www.oldsite.com/de --> goes to www.newsite.com (wrong)

instead of doing

www.oldsite.com/de/<everything> --> does nothing (works!)

thanks!

onetry

2:08 pm on Jun 22, 2011 (gmt 0)

10+ Year Member



Sorry I noticed that the forum changes syntax:

RewriteRule ^en/(.*)$ http: // www.newsite .com/en/ [R=301,L]
RewriteCond %{THE_REQUEST} !^[A-Z]+\ /de/
RewriteRule ^(.*) http: // www.newsite .com [R=301,L]

lucy24

6:13 pm on Jun 22, 2011 (gmt 0)

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



Well, that's why we keep telling you to use "example.com". This is a reserved name that the Forums have configured to not change into an active link. So if you want people to see the exact wording of the link, rather than going to the place it links to, use example.com for the domain.

The only problem is that when I surf:

www.oldsite.com/de --> goes to www.newsite.com (wrong)


Actually it's right according to your current rules, because

RewriteCond %{THE_REQUEST} !^[A-Z]+\ /de/


means "if the request does not begin with one or more capital letters, followed by a single space, followed by /de/" ...

I think what you actually want is ^/de/ since that's the very first thing after your domain name.

Oh, and the (.*)$ in the first rule should not be necessary, because it simply means "there may or may not be more stuff after the en/ part". You only need it if you plan to reuse it as $1