Tips wanted - translating website from English to another language dynamically.

They have: 12 posts

Joined: Jun 2006

(apologies if you've read my plea elsewhere)

Hi all.
You seem a knowledgeable bunch, so I wondered if you had some ideas for me. I'm after the elegant and/or industry-standard way to do this:

I have a site which has three sub-domains, each running essentially the same stuff from the same code, but each for a different 'customer'. The problem is, one of the sub-domains is for a Norwegian group, and the chap running it is keen for it to be in Norwegian (apparently some of them are too lazy to learn English Wink ). What I want to do is to give users a selection of flags to click on to select their language, which is stored as a cookie (easy enough so far).

Where it becomes tricky is generating the content. I don't want to translate each script manually (or rather, I don't want my Norwegian chum to do so) - I'd rather find a way of translating it online, one phrase at a time (by clicking a link in situ?). Oh, I use Perl, by the way!

I have some really poor ideas for this, but I thought I'd ask the question before barking any louder up the wrong tree.

Thanks!!!Laughing out loud

demonhale's picture

He has: 3,278 posts

Joined: May 2005

It wouldnt be the solution you may be looking for, but I think if you used CMS like joomla/mambo for example there are already some language plugs for those...

Or you could check the plugin developers for those language and see what they do to translate pages...

They have: 12 posts

Joined: Jun 2006

Thanks demonhale - but you're right, it's not really the thing!

I think I've been a bit too vague, so here's a bit more detail. Essentially, I'm after a more elegant way of doing the equivalent of

if ($language eq "french") {
print "J'ai $applecount pommes.";
} else {
print "I have $applecount apples.";
}
'
One crude way would be
print "$predefinedtext[1] $applecount $predefinedtext[2].";
#(where @predefinedtext is loaded from the appropriate file,
#or just stated explicitly as a hash array)
'
This is pretty hideous to edit/debug!

Another way might be

sub printtranslatedtext {
#some code here parses $_ for text between curly braces
#and replaces it if a translation is found
#in the appropriate hash array.
}

#and later on we call the function
printtranslatedtext("{I have} $applecount {apples}.");
#instead of the usual print......
'
The latter option seems CPU-heavy and still a bit crude, but does at least allow me to have a 'translate' mode where links/underlines appear by the chunks of text allowing the site owner to edit the translation array/file himself (and potentially making a Swahili version a goer!).

Something along those lines. I still think there must be a better way!
Confused Laughing out loud

Abhishek Reddy's picture

He has: 3,348 posts

Joined: Jul 2001

I suspect there is no simple solution. You may need to add a site-wide layer of abstraction somehow for the languages -- such as a translator, and/or a database of strings. If your program hasn't been designed with sufficient modularity, it could get very complicated.

The Perl, Unicode and i18N FAQ may be a good place to start. I quote:

Quote:
A1. Internationalizing a product involves issues about program design, application language features, cultural practices, fonts and often legacy clients. Most programmers face a rude awakening when first internationalizing an application after a career of only ASCII. Little details often become big headaches.

Smiling

They have: 12 posts

Joined: Jun 2006

Just to tidy things up, I'll tell you how I got around it - works nicely.

It's essentially my latter approach. I define a subroutine within my initialisation code (common for every page), listed below (with apologies for poor grammar!):

sub pt{
our $tstring=$_[0];
our $tstringnonewline=$_[1];
$tstring=~s/\{/|\~/g;
$tstring=~s/\}/\|/g;
my @tstring=split(/\|/,$tstring);
my $result='';
foreach (@tstring){
$tword=$_;
if(/^~/){
$tword=~s/\~//g;
if(substr($tword,0,1) eq "#"){
$tword=~s/\#//g;
$usedict='common';
$twordesc=$tword;
$twordesc=~s/([^\w()'*~!.-])/sprintf '%%%02x', ord $1/eg;
if($transcom{$tword} ne ""){
$tword=$transcom{$tword};
}
}else{
$usedict='specific';
$twordesc=$tword;
$twordesc=~s/([^\w()'*~!.-])/sprintf '%%%02x', ord $1/eg;
if($trans{$tword} ne ""){
$tword=$trans{$tword};
}
}
if($translate eq "yes"){
$tword="<span onClick=\"window.open('translate.cgi?text=$twordesc&usedict=$usedict','manualpredict','scrollbars,height=100,width=300');return false;\"><img src=/images/site/openphrase.gif width=5 height=7 border=0></span>$tword<span onClick=\"window.open('translate.cgi?text=$twordesc&usedict=$usedict','manualpredict','scrollbars,height=100,width=300');return false;\"><img src=/images/site/closephrase.gif width=5 height=7 border=0></span>";
}
}
$result=$result.$tword;
}
if($tstringnonewline){
print "$result";
}else{
print "$result\n";
}
return $result;
}
'

So essentially when coding I just have to type something like

pt("{I have} $apples {apples}");'

and the subroutine will look up anything inside the curly braces and translate it using a text dictionary, or leave it as it is if no translation is found. What's more, when in 'translate mode', translatable text is shown between two .gifs - click on one and you are prompted to enter a direct translation for that snippet of text. Evey page/script has its own dictionary (e.g. myhome.cgi would have a dictionary file myhome.txt), but if, for example, the word "apples" appears on many different pages, I can type my code thus:

pt("{I have} $apples {#apples}");'

and the '#' indicates that I use a common dictionary.

Language is selected by clicking a flag, which sets a cookie, and all I need now is a user who can speak the relevant language(s) to click on the translatable code in his/her own time.

Any questions, message me and I'll be happy to explain in more detail.

Thanks all.

Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.