Monday, 14 April 2008

detecting language settings for a website using @formula

The company I work for is a multinational in Europe and their website, reflecting Europe, is multilingual. The main url for this website however directs to a general page for all of Europe and is in English. And you get it, soon the request came for the site to be able to detect where the visitor is coming from and redirect this visitor to his local language homepage if it is available.
After some discussion we decided to use the setting for browser language rather than using the some IP-detect to determine the preferred language of the visitor.
Initially I started using the @LanguagePreference, which given the name of the function would be the right one to use. And it did for a while, until we started rolling out the website to countries where more than one language is spoken. Like Belgium with french and dutch or Switzerland with german, french and italian.
In these countries we would like the visitors to be redirected to the homepages of that country in the preferred language of the user. And that is where @LanguagePreference starts to fail.
Lets take an example: A Belgian visitor would most likely set their preferred language to french or dutch (vlemish), respectively fr-be & nl-be in the browser.
But @LanguagePreference respectively returns "fr" and "nl". And thus we do not have enough information to route the visitor to the proper homepage and they are redirected to the french or dutch homepage.
As I do not know all the @functions by heart, I turned to our admin (Dennis), to see if this could be solved in our firewall. But instead of configuring the firewall he pointed me to the @GetHTTPHeader function and its HTTP_Accept_Language parameter.
As it turns out, this function nicely returns a string of the set languages as set in the browser. Although the browsers have their differences, the major ones are comparable when languages are defined for countries that have multiple languages.

So here is how it works:
When opening the default homepage, before processing the rest of the page, some @function code determines the visitors language and does a dblookup to see if a homepage exists in visitors browser defined language. If so, a meta refresh is set to re-direct the visitor to the local language homepage.

This is the code that is used:
(Underneath the second rem block a keyword is retrieved as the naming of the languages in the site is not always in line with what the browsers use and somtimes the browsers are not using the same language coding.)

REM {== get the languagesettings from the browser (retrieve the first setting in the list) ==};
brlang := @LowerCase(@Subset(@Explode(@GetHTTPHeader("Accept-Language"); ",");1));
brlang_2 := @Left(brlang; 2);

REM {== get the Languages Browser keyword for languages that differ between browser and site ==};
REM {== and replace if preflang is found in browserlangs ==};
lb := @LowerCase(@DbLookup("Notes" : "NoCache"; ""; "luKeywords"; "languages browser"; 2; [FailSilent]));
browserlangs := @Left(lb; "~~");
sitelangs := @Right(lb; "~~");
@IsMember(brlang; browserlangs);
@Subset(@Subset(sitelangs; @Member(brlang; browserlangs)); -1);
@IsMember(brlang_2; browserlangs);
@Subset(@Subset(sitelangs; @Member(brlang_2; browserlangs)); -1);

REM {== try to get indexpage for user browserlanguage ==};
key := "index_" + @UpperCase(preflang) + ".html";
page := @DbLookup("Notes":"NoCache";""; "webpages"; key; 1; [FailSilent]);

REM {== if path_info ends in /, remove it, so it compares better to dbPath ==};
pathinf :=
@Right(Path_Info; 1) = "/";
@Left(Path_Info; @Length(Path_Info)-1);
REM {== show default homepage when path in url is not blank or identical to dbpath or ==};
REM {== if language homepage for browserlanguage is not found ==};
REM {== else reroute to language homepage ==};
pathinf != "" & pathinf != dbPath;
page = "";
"<meta http-equiv=\"refresh\" content=\"0;url="+dbPath + "/webpages/" + page +" />"

No comments: