Forum Moderators: phranque

Message Too Old, No Replies

Subdomain to pass as a query string parameter

subdomain,query string,wildcard,apache

         

Forsaken

9:30 pm on Aug 22, 2012 (gmt 0)

10+ Year Member



I'm making a multilingual website (for example: example.com, es.example.com, and de.example.com) and I'd like to pass the two-letter language codes as query string parameter "lang" for whatever page it lands on.

This is my entire .htaccess file right now:

RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !lang= [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(de|es)\.example\.com$ [NC]
RewriteRule ^(.*)$ $1?lang=%2 [NC,QSA,R,L]


When I type in
de.example.com/contact
, it rewrites to
de.example.com/contact?lang=de


So my question is, is there a way to omit the
?lang=de
at the end? A bit redundant. :(

(I also created a wildcard subdomain *)

Any help appreciated!

lucy24

4:16 am on Aug 23, 2012 (gmt 0)

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



:: looking around irritably ::

Y'know, I just spent three hours at the library to give someone else a chance to answer this question :(

The underlying issue is that I think you're a little hazy on the difference between a Rewrite and a Redirect. You can use mod_rewrite for both, but they do different things. In particular, it's not entirely clear what you want the human user to see. Subdomain, query string, neither, both?

Line by line:

RewriteCond %{QUERY_STRING} !lang= [NC]

Good start. You want to make sure that the language query isn't already present, which would send you into an infinite loop of
?lang=de&lang=de&lang=de&lang=de...

until the server puts its foot down-- generally after ten iterations.

RewriteCond %{HTTP_HOST} ^(www\.)?(de|es)\.example\.com$ [NC]

You don't need the anchored ^(www\.)? element, since you're not capturing. In fact, if this is intended to be a Rewrite, coming after any redirects, there's no ? about it. At this point, the requests either starts with www. or it doesn't.

RewriteRule ^(.*)$ $1?lang=%2 [NC,QSA,R,L]

When I type in de.example.com/contact, it rewrites to de.example.com/contact?lang=de

No, it doesn't. It redirects. The [R] flag converts the Rewrite into a temporary (302) Redirect. This is precisely what you don't want. Leave it out. It's doubly bad here because you didn't give the full protocol-plus-domain, so redirects will carry through with or without www, whichever way the original user requested it. Can you say Duplicate Content in three languages?

The [NC] flag is unnecessary here since you have not given any text to match.

Do you have different images, different stylesheets and so on, based on the language? Everything will run faster if you constrain the rule to requests with the appropriate "page" extension. Or no extension at all, if that's what you are doing. For example

RewriteRule ^([^.]*(/|\.php))$ {etc. --for pages in php}
or
RewriteRule ^([^.]*)$ {etc. --for extensionless pages}

Always put as much information as possible into the body of the Rule, so the server doesn't have to waste time checking Conditions all over again for every single request.

So my question is, is there a way to omit the ?lang=de at the end? A bit redundant.

Well, you put it there yourself. Can't blame the server for doing what you told it to. You explicitly said ?lang=%2 --and, to make double sure, you included a QSA flag to reappend any earlier queries.

All this is fine if you are doing a behind-the-scenes Rewrite. The upfront Redirect is a different issue. Which is where we came in.

Forsaken

3:00 am on Aug 26, 2012 (gmt 0)

10+ Year Member



Thanks for taking the time to explain it all! :D It clears up a lot of things.

This is what I have now:

RewriteCond %{QUERY_STRING} !lang= [NC]
RewriteCond %{HTTP_HOST} ^(de|es)\.example\.com$ [NC]
RewriteRule ^((?!files/).*\.php)$ $1?lang=%1 [QSA,NC,L]


...where all of my stylesheets/images/etc would be in the, say, files folder (it's a tiny site) and I make sure it ends with .php. Since I added text conditions, I assume I keep the [NC]? - Other than that, it works!

lucy24

10:48 am on Aug 26, 2012 (gmt 0)

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



Since I added text conditions, I assume I keep the [NC]?

Only if you're not concerned about Duplicate Content arising from people asking for .PHP or PhP or PHp or. With a Redirect it doesn't matter because everyone ends up in the same place. But Rewrites should never include [NC].

It also shouldn't be necessary in the Query String condition. I assume your page appends the query string itself, so it will always be in the same form. You certainly don't want to encourage users who think they're being smart by manually typing "LANG=DE" instead of clicking where you told them to click.

Does it work if you request the top-level domain index file-- or, for that matter, any other index file? Those would end in / rather than .php

There are still some issues with the rule. Sit tight. g1smd or someone like him is about to read you the riot act about using .* in the middle of an expression :)

Forsaken

1:37 pm on Aug 26, 2012 (gmt 0)

10+ Year Member



Okay, so I googled one of g1smd's explanations, I think~
webmasterworld.com/apache/4349526.htm

Does it work if you request the top-level domain index file-- or, for that matter, any other index file? Those would end in / rather than .php
It worked (same for the new code below).

Hmm, how about . .

RewriteCond %{REQUEST_URI} !^/files/ [NC]
RewriteCond %{HTTP_HOST} ^(de|es)\.example\.com [NC]
RewriteRule ^([^.]*\.php)$ $1?lang=%1 [QSA,L]