multilangue

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

multilangue

Laurent Kappler
Hi List,

I need to implement the use of different language on a website.

The idea we have is first for static text and second for dynamic text.

for static text, using a class Lang containing a hash table of array
like that:
a[ 'en' ][ 0 ] = 'Hi you're on';
a[ 'en' ][ 1 ] = 'It's on!';

a[ 'de' ][ 0 ] = 'Hallo, du bist on';
a[ 'de' ][ 1 ] = 'Das ist ON!';

etc...

and then set the language and request like that:
Lang.set( 'en' );
Lang.text( n );

And for the dynamic content from database, having one table for all text
in different language
A column per language, if adding a new language to the website we add a
new colomn.
And then in other tables, link text content to the lang table with the
id corresponding to the content.

Do you guys think that a good method ?

L




--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Bastiaan Wakkie
Hi L,

Your code will not be very readable after a while.
Why not just keep the default text ('en') as reference for readability
of your code:

a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
a[ 'en' ][ 'It is on' ] = 'It's on!';

a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
a[ 'de' ][ 'It is on' ] = 'Das ist ON!';

Land.set (en)
Lang.text( "Hi you are on");
Lang.set (de)
Lang.text( "Hi you are on");

Cheers,
Bastiaan

laurent wrote:

> Hi List,
>
> I need to implement the use of different language on a website.
>
> The idea we have is first for static text and second for dynamic text.
>
> for static text, using a class Lang containing a hash table of array
> like that:
> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
> a[ 'en' ][ 'It is on' ] = 'It's on!';
>
> a[ 'de' ][ 0 ] = 'Hallo, du bist on';
> a[ 'de' ][ 1 ] = 'Das ist ON!';
>
> etc...
>
> and then set the language and request like that:
> Lang.set( 'en' );
> Lang.text( 'en', 'Hi you're on' );
>
> And for the dynamic content from database, having one table for all
> text in different language
> A column per language, if adding a new language to the website we add
> a new colomn.
> And then in other tables, link text content to the lang table with the
> id corresponding to the content.
>
> Do you guys think that a good method ?
>
> L
>
>
>
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Ron Wheeler
Bastiaan Wakkie wrote:

> Hi L,
>
> Your code will not be very readable after a while.
> Why not just keep the default text ('en') as reference for readability
> of your code:
>
> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
> a[ 'en' ][ 'It is on' ] = 'It's on!';
>
> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>
> Land.set (en)
> Lang.text( "Hi you are on");
> Lang.set (de)
> Lang.text( "Hi you are on");
>
> Cheers,
> Bastiaan
>
> laurent wrote:
>> Hi List,
>>
>> I need to implement the use of different language on a website.
>>
>> The idea we have is first for static text and second for dynamic text.
>>
>> for static text, using a class Lang containing a hash table of array
>> like that:
>> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
>> a[ 'en' ][ 'It is on' ] = 'It's on!';
>>
>> a[ 'de' ][ 0 ] = 'Hallo, du bist on';
>> a[ 'de' ][ 1 ] = 'Das ist ON!';
>>
>> etc...
>>
>> and then set the language and request like that:
>> Lang.set( 'en' );
>> Lang.text( 'en', 'Hi you're on' );
>>
>> And for the dynamic content from database, having one table for all
>> text in different language
>> A column per language, if adding a new language to the website we add
>> a new colomn.
>> And then in other tables, link text content to the lang table with
>> the id corresponding to the content.
>>
>> Do you guys think that a good method ?
Not as good as making 3 column table. Text id, lang, text
Ron
>>
>> L
>>
>>
>>
>>
>



--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Gustavs
In reply to this post by Bastiaan Wakkie
2008/11/6 Bastiaan Wakkie <[hidden email]>:
> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
> a[ 'en' ][ 'It is on' ] = 'It's on!';
>
> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>

That's unsafe, it's better to define static identifiers for the
indices rather than using strings.

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Laurent Kappler
Yes I'm using arrays with numbers as index for each language and a list
containing my default language values. I will try with FastList.
Then I iterate through the list to find the word I want, with a counter
that I use as index in the other language array, to return the
corresponding value.

I could have directly use indexes but it's much more human readable in
the source like:
Lang.set( langue );

Lang.get( 'The sentence needed here' );//if langue = default language,
it return the input string

L

Gust a écrit :

> 2008/11/6 Bastiaan Wakkie <[hidden email]>:
>  
>> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
>> a[ 'en' ][ 'It is on' ] = 'It's on!';
>>
>> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
>> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>>
>>    
>
> That's unsafe, it's better to define static identifiers for the
> indices rather than using strings.
>
>  


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Owen Durni
You could likely speed up that algorithm by making a hash from English
String to index rather than searching through the entire array to find
the index.

--Owen

On Thu, Nov 6, 2008 at 5:47 PM, laurent <[hidden email]> wrote:

> Yes I'm using arrays with numbers as index for each language and a list
> containing my default language values. I will try with FastList.
> Then I iterate through the list to find the word I want, with a counter that
> I use as index in the other language array, to return the corresponding
> value.
>
> I could have directly use indexes but it's much more human readable in the
> source like:
> Lang.set( langue );
>
> Lang.get( 'The sentence needed here' );//if langue = default language, it
> return the input string
>
> L
>
> Gust a écrit :
>>
>> 2008/11/6 Bastiaan Wakkie <[hidden email]>:
>>
>>>
>>> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
>>> a[ 'en' ][ 'It is on' ] = 'It's on!';
>>>
>>> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
>>> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>>>
>>>
>>
>> That's unsafe, it's better to define static identifiers for the
>> indices rather than using strings.
>>
>>
>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Laurent Kappler

hm you mean array[ 'default language string' ] = index ?

is still good if the string can be very longue?
I used a list not an array. I'm not sure fastList is faster for neko but
it should be.

If that list is too big I guess there should be some kind of alphabetic
sorting at initialisation and then make an alphabetic(dicotomic) search.
Those kind of list get easealy to 300 entry. I don't know it that's big.
If I want some alphabetic search I will need an array for index access.
L

Owen Durni a écrit :

> You could likely speed up that algorithm by making a hash from English
> String to index rather than searching through the entire array to find
> the index.
>
> --Owen
>
> On Thu, Nov 6, 2008 at 5:47 PM, laurent <[hidden email]> wrote:
>  
>> Yes I'm using arrays with numbers as index for each language and a list
>> containing my default language values. I will try with FastList.
>> Then I iterate through the list to find the word I want, with a counter that
>> I use as index in the other language array, to return the corresponding
>> value.
>>
>> I could have directly use indexes but it's much more human readable in the
>> source like:
>> Lang.set( langue );
>>
>> Lang.get( 'The sentence needed here' );//if langue = default language, it
>> return the input string
>>
>> L
>>
>> Gust a écrit :
>>    
>>> 2008/11/6 Bastiaan Wakkie <[hidden email]>:
>>>
>>>      
>>>> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
>>>> a[ 'en' ][ 'It is on' ] = 'It's on!';
>>>>
>>>> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
>>>> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>>>>
>>>>
>>>>        
>>> That's unsafe, it's better to define static identifiers for the
>>> indices rather than using strings.
>>>
>>>
>>>      
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>>    
>
>  


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Owen Durni
On Fri, Nov 7, 2008 at 7:51 AM, laurent <[hidden email]> wrote:

>
> hm you mean array[ 'default language string' ] = index ?
>
> is still good if the string can be very longue?
> I used a list not an array. I'm not sure fastList is faster for neko but it
> should be.
>
> If that list is too big I guess there should be some kind of alphabetic
> sorting at initialisation and then make an alphabetic(dicotomic) search.
> Those kind of list get easealy to 300 entry. I don't know it that's big. If
> I want some alphabetic search I will need an array for index access.
> L

I was getting at something like this (some code omitted below, may not
compile after a copy/paste)

Instead of having to traverse the whole list, you just look up the
correct index in a Hash. You can skip traversing the list by using a
hashtable (I think all platforms support an efficient hash for String
types).

var dict :Array<Array<String>>;
inline static EN :Int = 0;
inline static DE :Int = 1;

var dictmap :Hash<Int>;

function addDict( canonical :String, langcode :Int, langtext :String ) :Void
{
  var index :Int;

  if( !dictmap.exists( canonical ) )
  {
    index = dict.length;
    dictmap.put( canonical, index );
  }
  else
  {
    index = dictmap.get( canonical );
  }

  dict[index][langcode] = langtext;
}

function findDict( canonical :String, langcode :Int ) :String
{
  return dict[dictmap.get(canonical)][langcode];
}

addDict( "Hi you are on", EN, "Hi you're on" );
addDict( "It is on", EN, "It's on!" );
addDict( "Hi you are on", DE, "Hallo, du bist on" );
addDict( "It is on", DE, "Das ist ON!" );

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Laurent Kappler
Yes, I looked closer about Hash table, and actually the hash function is
doing the job for finding the index.
Still I'm not sure about long character chain but I'll give it a try.
Thanks for the neat method.

L


Owen Durni a écrit :

> On Fri, Nov 7, 2008 at 7:51 AM, laurent <[hidden email]> wrote:
>  
>> hm you mean array[ 'default language string' ] = index ?
>>
>> is still good if the string can be very longue?
>> I used a list not an array. I'm not sure fastList is faster for neko but it
>> should be.
>>
>> If that list is too big I guess there should be some kind of alphabetic
>> sorting at initialisation and then make an alphabetic(dicotomic) search.
>> Those kind of list get easealy to 300 entry. I don't know it that's big. If
>> I want some alphabetic search I will need an array for index access.
>> L
>>    
>
> I was getting at something like this (some code omitted below, may not
> compile after a copy/paste)
>
> Instead of having to traverse the whole list, you just look up the
> correct index in a Hash. You can skip traversing the list by using a
> hashtable (I think all platforms support an efficient hash for String
> types).
>
> var dict :Array<Array<String>>;
> inline static EN :Int = 0;
> inline static DE :Int = 1;
>
> var dictmap :Hash<Int>;
>
> function addDict( canonical :String, langcode :Int, langtext :String ) :Void
> {
>   var index :Int;
>
>   if( !dictmap.exists( canonical ) )
>   {
>     index = dict.length;
>     dictmap.put( canonical, index );
>   }
>   else
>   {
>     index = dictmap.get( canonical );
>   }
>
>   dict[index][langcode] = langtext;
> }
>
> function findDict( canonical :String, langcode :Int ) :String
> {
>   return dict[dictmap.get(canonical)][langcode];
> }
>
> addDict( "Hi you are on", EN, "Hi you're on" );
> addDict( "It is on", EN, "It's on!" );
> addDict( "Hi you are on", DE, "Hallo, du bist on" );
> addDict( "It is on", DE, "Das ist ON!" );
>
>  


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Owen Durni
On Sun, Nov 9, 2008 at 9:01 PM, laurent <[hidden email]> wrote:
> Yes, I looked closer about Hash table, and actually the hash function is
> doing the job for finding the index.
> Still I'm not sure about long character chain but I'll give it a try.
> Thanks for the neat method.
>
> L

I would have to do some testing, but I would imagine that if the
length of the strings you are hashing are much longer than the number
of words in your lookup dictionary then some other data structure
might be faster (a balanced BST variant or a compressed trie).

Using long keys in a dictionary structure is always going to slow down
runtime, as you have to run down every character when you are
comparing keys for equality.

--Owen

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Ian Thomas
In reply to this post by Laurent Kappler
Laurent,
   The most common' approach for this is to adopt some sort of string
ID for the string, rather than using a language string as the key.

for example:

button.label=Lang.get("save_button_label");
dialogue.title=Lang.set("save_dialogue_title");

or similar.

This is partly for compactness, and partly because it avoids problems
with the source language string i.e. unusual characters tend to make
it difficult to use whole strings as keys.

The other reason to go for string IDs instead of full language strings
is that the IDs are much more specific; I suspect there are situations
where in one language you use the same text for a number of different
items (and so it would be what you use in Lang.get()), but in a
different language you want it to vary between items. Often to do with
the conjugation of verbs and such.

By which I mean - differentiate the keys/IDs by the _purpose_ of the
string. Not by the _value_ of the string.

HTH,
   Ian

On Thu, Nov 6, 2008 at 10:47 PM, laurent <[hidden email]> wrote:

> Yes I'm using arrays with numbers as index for each language and a list
> containing my default language values. I will try with FastList.
> Then I iterate through the list to find the word I want, with a counter that
> I use as index in the other language array, to return the corresponding
> value.
>
> I could have directly use indexes but it's much more human readable in the
> source like:
> Lang.set( langue );
>
> Lang.get( 'The sentence needed here' );//if langue = default language, it
> return the input string
>
> L
>
> Gust a écrit :
>>
>> 2008/11/6 Bastiaan Wakkie <[hidden email]>:
>>
>>>
>>> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
>>> a[ 'en' ][ 'It is on' ] = 'It's on!';
>>>
>>> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
>>> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>>>
>>>
>>
>> That's unsafe, it's better to define static identifiers for the
>> indices rather than using strings.
>>
>>
>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Laurent Kappler
Ian Thomas a écrit :
> Laurent,
>    The most common' approach for this is to adopt some sort of string
> ID for the string, rather than using a language string as the key.
>
> for example:
>
> button.label=Lang.get("save_button_label");
> dialogue.title=Lang.set("save_dialogue_title");
>  
hm yes so we got an array for each language with all the same indexes.
That's a good way to do it.
The compressed trie looks interesting to implement. I saw the BTree in
colhx, maybe I will take some time to make a LPC-Trie for the fun of it :)
Then I can serialized the filled class to be shared with any user
session, and update it only on language modifications, stuff that occure
once a something long.

L

> or similar.
>
> This is partly for compactness, and partly because it avoids problems
> with the source language string i.e. unusual characters tend to make
> it difficult to use whole strings as keys.
>
> The other reason to go for string IDs instead of full language strings
> is that the IDs are much more specific; I suspect there are situations
> where in one language you use the same text for a number of different
> items (and so it would be what you use in Lang.get()), but in a
> different language you want it to vary between items. Often to do with
> the conjugation of verbs and such.
>
> By which I mean - differentiate the keys/IDs by the _purpose_ of the
> string. Not by the _value_ of the string.
>
> HTH,
>    Ian
>
> On Thu, Nov 6, 2008 at 10:47 PM, laurent <[hidden email]> wrote:
>  
>> Yes I'm using arrays with numbers as index for each language and a list
>> containing my default language values. I will try with FastList.
>> Then I iterate through the list to find the word I want, with a counter that
>> I use as index in the other language array, to return the corresponding
>> value.
>>
>> I could have directly use indexes but it's much more human readable in the
>> source like:
>> Lang.set( langue );
>>
>> Lang.get( 'The sentence needed here' );//if langue = default language, it
>> return the input string
>>
>> L
>>
>> Gust a écrit :
>>    
>>> 2008/11/6 Bastiaan Wakkie <[hidden email]>:
>>>
>>>      
>>>> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
>>>> a[ 'en' ][ 'It is on' ] = 'It's on!';
>>>>
>>>> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
>>>> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>>>>
>>>>
>>>>        
>>> That's unsafe, it's better to define static identifiers for the
>>> indices rather than using strings.
>>>
>>>
>>>      
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>>    
>
>  


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

clemos
Hi

Btw:
http://lists.motion-twin.com/pipermail/haxe/2006-December/006216.html
What did that become ? A gettext support would really be great for
these kind of issues...

+++++
Clément

On Tue, Nov 11, 2008 at 5:59 PM, laurent <[hidden email]> wrote:

> Ian Thomas a écrit :
>>
>> Laurent,
>>   The most common' approach for this is to adopt some sort of string
>> ID for the string, rather than using a language string as the key.
>>
>> for example:
>>
>> button.label=Lang.get("save_button_label");
>> dialogue.title=Lang.set("save_dialogue_title");
>>
>
> hm yes so we got an array for each language with all the same indexes.
> That's a good way to do it.
> The compressed trie looks interesting to implement. I saw the BTree in
> colhx, maybe I will take some time to make a LPC-Trie for the fun of it :)
> Then I can serialized the filled class to be shared with any user session,
> and update it only on language modifications, stuff that occure once a
> something long.
>
> L
>
>> or similar.
>>
>> This is partly for compactness, and partly because it avoids problems
>> with the source language string i.e. unusual characters tend to make
>> it difficult to use whole strings as keys.
>>
>> The other reason to go for string IDs instead of full language strings
>> is that the IDs are much more specific; I suspect there are situations
>> where in one language you use the same text for a number of different
>> items (and so it would be what you use in Lang.get()), but in a
>> different language you want it to vary between items. Often to do with
>> the conjugation of verbs and such.
>>
>> By which I mean - differentiate the keys/IDs by the _purpose_ of the
>> string. Not by the _value_ of the string.
>>
>> HTH,
>>   Ian
>>
>> On Thu, Nov 6, 2008 at 10:47 PM, laurent <[hidden email]> wrote:
>>
>>>
>>> Yes I'm using arrays with numbers as index for each language and a list
>>> containing my default language values. I will try with FastList.
>>> Then I iterate through the list to find the word I want, with a counter
>>> that
>>> I use as index in the other language array, to return the corresponding
>>> value.
>>>
>>> I could have directly use indexes but it's much more human readable in
>>> the
>>> source like:
>>> Lang.set( langue );
>>>
>>> Lang.get( 'The sentence needed here' );//if langue = default language, it
>>> return the input string
>>>
>>> L
>>>
>>> Gust a écrit :
>>>
>>>>
>>>> 2008/11/6 Bastiaan Wakkie <[hidden email]>:
>>>>
>>>>
>>>>>
>>>>> a[ 'en' ][ 'Hi you are on' ] = 'Hi you're on';
>>>>> a[ 'en' ][ 'It is on' ] = 'It's on!';
>>>>>
>>>>> a[ 'de' ][ 'Hi you are on' ] = 'Hallo, du bist on';
>>>>> a[ 'de' ][ 'It is on' ] = 'Das ist ON!';
>>>>>
>>>>>
>>>>>
>>>>
>>>> That's unsafe, it's better to define static identifiers for the
>>>> indices rather than using strings.
>>>>
>>>>
>>>>
>>>
>>> --
>>> haXe - an open source web programming language
>>> http://haxe.org
>>>
>>>
>>
>>
>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: multilangue

Nicolas Cannasse
clemos a écrit :
> Hi
>
> Btw:
> http://lists.motion-twin.com/pipermail/haxe/2006-December/006216.html
> What did that become ? A gettext support would really be great for
> these kind of issues...

We are finally using another method instead of gettext, which uses an
external XML file and haxe.xml.Proxy.

See : http://ncannasse.fr/blog/about_haxe.xml.proxy

Nicolas

--
haXe - an open source web programming language
http://haxe.org