Forum Moderators: coopster

Message Too Old, No Replies

Language detection script

Http_accept_language

         

encyclo

9:17 pm on May 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've got a bilingual (French/English) site, and in order to deliver the content in the most appropriate language, I'm sniffing the HTTP_ACCEPT_LANGUAGE and redirecting based on what I get (the user can change language later if I get it wrong!). At the moment, I'm using this:

<?php
$userlang=($_SERVER["HTTP_ACCEPT_LANGUAGE"]);
$userlang=substr($userlang,0,2);
if ($userlang== fr ) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: ./fr/");
exit;}
else {
header("HTTP/1.1 301 Moved Permanently");
header("Location: ./en/");
exit;}
?>

This works just fine if the user's first choice or language is French ("fr"), but I'm only scanning the first two letters.

The output of a typical HTTP_ACCEPT_LANGUAGE would be:

en-ca,fr-ca;q=0.8,nl;q=0.5,de;q=0.3

with fields separated by commas (the q= bit is just the weighting).

Trouble is, what happens if the user's first choice is, say, Spanish, with French second? With my code, they'd get the default (english), but I'd like them to get French.

I can split it into an array, read only the first two characters, and go from there. I've got this far:

<?php 
$langs=explode(",",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
$first=substr($langs[0],0,2);
echo "First choice is: ".$first."<br>";
$second=substr($langs[1],0,2);
echo "Second choice is: ".$second;
?>

Thing is, I'm a bit stuck with the logic of it all, and I'm not sure how to go from here. I want to scan the options, read just the first two letters of each and pick the first which occurs, either "fr" or "en", with "en" supplied if "fr" is absent.

Any ideas on how I can do this?

Another code example in this thread [webmasterworld.com]

Timotheos

12:12 am on May 12, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi encyclo,

Funny I've been thinking about doing this but haven't got around to it yet... well until you spurred me on. Here's what I've come up with. Let me know if you find any problems or you come up with a better way. I have over 30 languages to choose from on my site (whew).

<?php
//check first to see if they've been nice and
//set the language
if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {

//grab all the languages
$langs=explode(",",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);

//start going through each one
foreach ($langs as $value) {

//select only the first two letters
$choice=substr($value,0,2);

//redirect to the different language page
//based on their first chosen language
switch ($choice) {
case "fr":
Header("Location: french.php");
exit;
case "en":
Header("Location: english.php");
exit;
case "es":
Header("Location: spanish.php");
exit;
}
}
}

//If the language is not set then use this
//as default
else {
Header("Location: english.php");
exit;
}
?>

Now we just got to figure out how to set a cookie and have it override this automatic selection if it's all ready set.

encyclo

12:31 am on May 12, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks Timotheos, I had got a bit lost in the logic with my code, but your code works perfectly.

I work mostly on Canadian sites, where bilingual content is the norm, but I'm sick of getting a "Choose your language" home page - it seems such a waste. At the moment, I only want to use the script on the home page, and I've got a "switch language" option available to jump to the other language option if required. As for a site in 30 languages, this kind of thing must be very useful...

Of course, the cookie thing would be good too... I'll have to start reading up on this!

Timotheos

5:06 am on May 12, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Funny thing happened to me. I was testing this out in different languages and forgot to reset my language settings. I then went to the MS Windows Update page and it came up in Russian. Doh! Took me a few seconds to remember that I had been playing with my language settings ;-)

ergophobe

3:59 pm on May 12, 2004 (gmt 0)

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



One quick point Timotheos,

The way you have it set up, there's no default for the case where there is a language header, but none of the languages are in the choices given by your swithc statement(in other words, your switch needs a default).

How about this for some real messy pseudo code.

$loc = 'english.php'; // sets default

if (there's a cookie with a language value)
{
$loc = cookie value
}

elseif (there's a language header)
{
$found = false;
for(!$found and still not at end of array){

switch (value from language header)
{
case 'fr':
$loc = 'french.php';
$found = true;
break;

case 'nl':
$loc = dutch;
$found = true;
break;
}
}
}
header("Location: $loc");

Note, you could also stick with the foreach and test within each case statement. In that solution you always iterate through the entire language header array, but since that will only have a few elements, it shouldn't matter.

Timotheos

4:56 pm on May 12, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi ergophobe,

Good catch on the missing logic! I had thought of that and originally put a default in the switch condition but that didn't work during a case where the first language is not supported but the second choice language would be. So, I took it out and then forgot about implementing it some other way.

Thanks,
Tim

ergophobe

5:23 pm on May 12, 2004 (gmt 0)

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



Having seen a bunch of your posts, I figured that was not an error that would make it into your final code. I did think it was worth it to point out in case someone came here to copy and paste though.

Cheers,

Tom