Localizing a webapp

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

Localizing a webapp

Lars A. Gundersen-2
Hi, all!

I've developed http://www.sonorait.no/ (in Norwegian) and the online  
survey web app Laguna Survey residing there. The next big step is to  
localize both the webapp and the website in general, i.e. developing a  
methodology to allow it to be served and developed/maintained in  
different languages, and then to implement English.
There was a thread about that in desember last year:
http://www.nabble.com/Approach-to-multi-lingual-website...-td14395119.html#a14395119

I was just wondering if Simon Fredrikson would care to elaborate on  
the approach he suggested there, and if anybody else has some  
suggestions for best practice, or simply examples on how you have done  
it. Would be very helpful, I am sure.
I can't find the thread that Bil Corry referenced there, BTW.

Cheers,
Lars
--
Lars A. Gundersen
http://www.larsagundersen.no/ • +47 91 64 46 10


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Marc Pope
The way I've seen most apps done is wherever there is text, make a  
variable, e.g. [$text_confirmdelete]. Make a text file containing all  
the terms and call it English.txt and another text file called  
Spanish.txt, etc and then it will be easy to translate. In Lasso, you  
can look in that directory for all the files and have a popup menu to  
switch between whatever files are in the directory.

IMO, this makes it easy for even non-programmers to make a translated  
version.

Your text file might look like this, which would be fairly easy to  
parse.

text_confirmdeleterecord
Please confirm you wish to delete this record.
-
text_login
Please enter your username and password:
-
etc..

Marc

On Aug 13, 2008, at 8:27 AM, Lars A. Gundersen wrote:

> Hi, all!
>
> I've developed http://www.sonorait.no/ (in Norwegian) and the online  
> survey web app Laguna Survey residing there. The next big step is to  
> localize both the webapp and the website in general, i.e. developing  
> a methodology to allow it to be served and developed/maintained in  
> different languages, and then to implement English.
> There was a thread about that in desember last year:
> http://www.nabble.com/Approach-to-multi-lingual-website...-td14395119.html#a14395119
>
> I was just wondering if Simon Fredrikson would care to elaborate on  
> the approach he suggested there, and if anybody else has some  
> suggestions for best practice, or simply examples on how you have  
> done it. Would be very helpful, I am sure.
> I can't find the thread that Bil Corry referenced there, BTW.
>
> Cheers,
> Lars
> --
> Lars A. Gundersen
> http://www.larsagundersen.no/ • +47 91 64 46 10
>
>
> --
> This list is a free service of LassoSoft: http://www.LassoSoft.com/
> Search the list archives: http://www.ListSearch.com/Lasso/Browse/
> Manage your subscription: http://www.ListSearch.com/Lasso/
>


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

dguardiola
> Your text file might look like this, which would be fairly easy to  
> parse.
>
> text_confirmdeleterecord
> Please confirm you wish to delete this record.
> -
> text_login
> Please enter your username and password:
> -

fairly easy approach , i'm taking it :)
what about an XML file and using xml_tree to find out the good  
variable ?

<var>text_login</var>
        <en>Please enter your username and password:</en>
        <fr>Entrez vos identifiants</fr>
</var>

--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Fletcher Sandbeck-3
In reply to this post by Marc Pope
On 8/13/08 at 11:09 AM, [hidden email] (Marc) wrote:

>The way I've seen most apps done is wherever there is text, make a
>variable, e.g. [$text_confirmdelete]. Make a text file containing all
>the terms and call it English.txt and another text file called
>Spanish.txt, etc and then it will be easy to translate. In Lasso, you
>can look in that directory for all the files and have a popup menu to
>switch between whatever files are in the directory.
>
>IMO, this makes it easy for even non-programmers to make a translated version.

I'd rather do a tag like [Localize: 'confirmdelete'].  This
allows the site author to create as many localizable text
snippets as they need without polluting the variable namespace.  
And, the word "Localize" helps make the code self documenting.

This is one way to implement that.  The globals would be defined
at startup.  The maps of terms would be loaded from the file you
are discussing.

global('localize_strings') =
map('en'=map('confirmdelete'='Confirm Delete'));
global('localize_default') = 'en';

define_tag('localize', -required='key', -optional='lang');
     !local_defined('lang') ? local('lang') =
if_empty(global('localize_default'), 'en');

     local('map') = global('localize_strings')->find(#lang);
     return(#map->find(#key));
/define_tag;

localize('confirmdelete');

Hope this helps,

[fletcher]

--
Fletcher Sandbeck                         [hidden email]
LassoSoft, LLC                          http://www.lassosoft.com


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Alan Linnenbank
Now all you have to do is hash the keys so you can even make case  
differences work!

lastname
vs
Lastname

Alan

On Aug 13, 2008, at 17:34 , Fletcher Sandbeck wrote:

> On 8/13/08 at 11:09 AM, [hidden email] (Marc) wrote:
>
>> The way I've seen most apps done is wherever there is text, make a
>> variable, e.g. [$text_confirmdelete]. Make a text file containing all
>> the terms and call it English.txt and another text file called
>> Spanish.txt, etc and then it will be easy to translate. In Lasso, you
>> can look in that directory for all the files and have a popup menu to
>> switch between whatever files are in the directory.
>>
>> IMO, this makes it easy for even non-programmers to make a  
>> translated version.
>
> I'd rather do a tag like [Localize: 'confirmdelete'].  This allows  
> the site author to create as many localizable text snippets as they  
> need without polluting the variable namespace.  And, the word  
> "Localize" helps make the code self documenting.
>
> This is one way to implement that.  The globals would be defined at  
> startup.  The maps of terms would be loaded from the file you are  
> discussing.
>
> global('localize_strings') = map('en'=map('confirmdelete'='Confirm  
> Delete'));
> global('localize_default') = 'en';
>
> define_tag('localize', -required='key', -optional='lang');
>    !local_defined('lang') ? local('lang') =  
> if_empty(global('localize_default'), 'en');
>
>    local('map') = global('localize_strings')->find(#lang);
>    return(#map->find(#key));
> /define_tag;
>
> localize('confirmdelete');
>
> Hope this helps,
>
> [fletcher]
>
> --
> Fletcher Sandbeck                         [hidden email]
> LassoSoft, LLC                          http://www.lassosoft.com
>
>
> --
> This list is a free service of LassoSoft: http://www.LassoSoft.com/
> Search the list archives: http://www.ListSearch.com/Lasso/Browse/
> Manage your subscription: http://www.ListSearch.com/Lasso/
>


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Jolle Carlestam-2
In reply to this post by Lars A. Gundersen-2
Knop has a type for localizing. You build a language object like this:

        var: 'lang_errormessages' = knop_lang( -default = $defLanguage);
This object is cached for performance.

Populate it (Swedish):
        $lang_errormessages -> (addlanguage( -language = 'sv',
                        -strings = (map(
                        'code0' = 'Inget fel',
                        'code-1728' = 'Inga poster hittades', // standard Lasso error code
                       
                        // database errors 7000
                        'code7001' = 'Begärd tabell kunde inte hittas',
                        'code7002' = 'Nyckelfält inte specificerat (Keyfield)',
                        'code7003' = 'Låsfält inte specificerat (Lockfield)',
                        'code7004' = 'Ingen användare specificerad för postlåsning',
/.../
                        // Application specific errors 8500
                        'code8501' = 'Felaktigt utformat datum.',
                        'code8502' = 'Antal platser måste vara en siffra.',
                )
                        );

(English)
        $lang_errormessages -> (addlanguage: -language = 'en',
                        -strings = (map:
                        'code0' = 'No error',
                        'code-1728' = 'No records found', // standard Lasso error code
/.../
                )
                        );

Another example:
        $lang_btns -> addlanguage( -language = 'en',
                        -strings = map(
                                'logoutBtn' = 'Log out',
                                'logoutImgBtn' = '<img src="/jinaimg/logout_btn_en.gif" alt="Log  
out" border="0">',
                                'loginBtn' = 'Log in',
                                'saveBtn' = 'Save',
                                'addBtn' = 'Add',
                                'searchBtn' = 'Search',
                                'deleteBtn' = 'Delete',
                                'cancelBtn' = 'Cancel',
                                'resetBtn' = 'Reset',
                                'sendBtn' = 'Send',
                                'createBtn' = 'Create',
                                )
                        );

And call it like this:
$lang_errormessages -> code7001

I find it very easy to use.

Knop_lang can handle default languages, detect a language from the  
http header as well as user chosen.

I let the user choose by having flags with available languages. And  
then set a cookie with either default language value or the user choice.

And it can handle dynamic parts/variable. Here's an example from the  
documentation:
        $lang_messages -> loggedin( -replace = array( field( 'firstname'),  
field( 'lastname')));

HDB
Jolle

13 aug 2008 kl. 14.27 skrev Lars A. Gundersen:

>
> Hi, all!
>
> I've developed http://www.sonorait.no/ (in Norwegian) and the online
> survey web app Laguna Survey residing there. The next big step is to
> localize both the webapp and the website in general, i.e. developing a
> methodology to allow it to be served and developed/maintained in
> different languages, and then to implement English.
> There was a thread about that in desember last year:
> http://www.nabble.com/Approach-to-multi-lingual-website...-td14395119.html#a14395119
>
> I was just wondering if Simon Fredrikson would care to elaborate on
> the approach he suggested there, and if anybody else has some
> suggestions for best practice, or simply examples on how you have done
> it. Would be very helpful, I am sure.
> I can't find the thread that Bil Corry referenced there, BTW.
>
> Cheers,
> Lars
> --
> Lars A. Gundersen
> http://www.larsagundersen.no/ • +47 91 64 46 10
>
>
> --
> This list is a free service of LassoSoft: http://www.LassoSoft.com/
> Search the list archives: http://www.ListSearch.com/Lasso/Browse/
> Manage your subscription: http://www.ListSearch.com/Lasso/
>


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Nikolaj de Fine Licht
In reply to this post by Lars A. Gundersen-2
In addition to the other's answers and in addition to the referenced  
thread mentioning localisation in PageBlocks I would like to add, that  
the PageBlocks frameworks offers localisation means on all levels and  
with various approaches. But od course, for a project already done its  
probably not convenient to think of squeezing it into a framework...

The principles mentioned by Fletcher is quite much those on which  
PageBlocks' localisation is based. You have libraries holding the  
different language versions of text threads and you have tags that  
pick the right thread based on a language input.

/nikolaj

On 13. aug 2008, at 14:27, Lars A. Gundersen wrote:

> Hi, all!
>
> I've developed http://www.sonorait.no/ (in Norwegian) and the online  
> survey web app Laguna Survey residing there. The next big step is to  
> localize both the webapp and the website in general, i.e. developing  
> a methodology to allow it to be served and developed/maintained in  
> different languages, and then to implement English.
> There was a thread about that in desember last year:
> http://www.nabble.com/Approach-to-multi-lingual-website...-td14395119.html#a14395119
>
> I was just wondering if Simon Fredrikson would care to elaborate on  
> the approach he suggested there, and if anybody else has some  
> suggestions for best practice, or simply examples on how you have  
> done it. Would be very helpful, I am sure.
> I can't find the thread that Bil Corry referenced there, BTW.

--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Gary Clark-2
In reply to this post by Lars A. Gundersen-2
Hi list,

It was me that posed the question and the site is now live and working  
fine.

In the end I had an include at the top of each page that had a big  
conditional that checked the domain and established a pre-defined set  
of variables for the 'static' content of the site with pre translated  
text and a var outlining the language '$myLanguage' like 'en' and  
'fr'. This approach was lead by SEO, as they wanted to have a  
different domain for each language.

Then the CMS had provision for input for each available language for  
fields like 'header_en' and 'header_fr' for example, then each field  
is called by the following [Field:'header_'$myLanguage].

Just in case anyone was interested.

Gary Clark



> Hi, all!
>
> I've developed http://www.sonorait.no/ (in Norwegian) and the online  
> survey web app Laguna Survey residing there. The next big step is to  
> localize both the webapp and the website in general, i.e. developing  
> a methodology to allow it to be served and developed/maintained in  
> different languages, and then to implement English.
> There was a thread about that in desember last year:
> http://www.nabble.com/Approach-to-multi-lingual-website...-td14395119.html#a14395119
>
> I was just wondering if Simon Fredrikson would care to elaborate on  
> the approach he suggested there, and if anybody else has some  
> suggestions for best practice, or simply examples on how you have  
> done it. Would be very helpful, I am sure.
> I can't find the thread that Bil Corry referenced there, BTW.
>
> Cheers,
> Lars
> --
> Lars A. Gundersen
> http://www.larsagundersen.no/ • +47 91 64 46 10
>
>
> --
> This list is a free service of LassoSoft: http://www.LassoSoft.com/
> Search the list archives: http://www.ListSearch.com/Lasso/Browse/
> Manage your subscription: http://www.ListSearch.com/Lasso/
>
>


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Johan Solve
In reply to this post by Jolle Carlestam-2
On Wed, Aug 13, 2008 at 6:22 PM, Jolle Carlestam <[hidden email]> wrote:
> Knop has a type for localizing.

Let me add that you can use just the localization feature of Knop if
you want, and nothing else. Pick and chose - no need to use all of
Knop for your project just to be able to use the localization.

I'll tell you more about this on Lasso Developers Conference...

--
Mvh
Johan Sölve
____________________________________
Montania System AB
Halmstad Stockholm Malmö
http://www.montania.se

Johan Sölve
Mobil +46 709-51 55 70
[hidden email]

Kristinebergsvägen 17, S-302 41 Halmstad, Sweden
Telefon +46 35-136800 | Fax +46 35-136801

--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Lars A. Gundersen-2
Thanks for all the pointers, I'll have to code and mull over this in  
the coming weeks. So you'll have to excuse me if I reopen this thread  
later.

Of course, while I didn't say it explicitly, the backend of Laguna  
Survey is 100% Lasso. It's been a blast developing, I must say, maybe  
especially the Javascript-to-Lasso-to-Javascript XML parsing used for  
the survey data format. Lasso rocks!

Yes, I was wondering if someone would throw out a "I'll talk about  
exactly that during Lasso Dev" answer. I can kick myself all I want,  
but I still can't attend.

Lars
--
Lars A. Gundersen
http://www.larsagundersen.no/ • +47 91 64 46 10


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Bil Corry-3
In reply to this post by Lars A. Gundersen-2
Lars A. Gundersen wrote on 8/13/2008 7:27 AM:
> I can't find the thread that Bil Corry referenced there, BTW.

It still works:

        <http://www.listsearch.com/Lasso/Thread/index.lasso?18706>

Or you can read it on Nabble instead if you want:

        <http://www.nabble.com/-ann--PageBlocks-Updated-to-5.2.2-td11483934.html>


- Bil


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Jussi Hirvi
In reply to this post by Gary Clark-2
I see the dye is cast already, but here's another approach to localization.
The good side is that the page code looks good and intuitive. And the
translations file is easy to make. The bad side is that if the site is
large, some conflicts may arise.

In the LassoBlogger blogware I have used a system which was copied from
WordPress - I'm not sure if WP still uses this. LassoBlogger code is easily
available at http://www.lassoforge.com .

In a config file is a language selector, like:
    var:'lang' = 'fi';

In the code every translatable text string is marked like this:
    str:'Please give an email address';

Str is a custom tag. Namespace (like "LB_") is omitted in the tag name, to
keep it short.

Thus English is the default language (could as well be Norwegian).

The actual translations are in /languages/fi.inc, where "fi" means Finnish,
in this case. The main part of that file is a long map, in alphabetical
order:

var:'mTranslations' = (Map:
'A comment has been added to your blog at'      = 'Blogiisi on lisätty
kommentti, ks.', // used in email message
'and start writing posts (if your initial permissions allow it)' = 'ja
ryhtyä
kirjoittamaan blogiviestejä (jos uudelle käyttäjälle myönnetyt oikeudet
sallivat tämän)', // use-registered.inc
'and your password' =  'ja salasanasi', // use-registered.inc
'Archives' = 'Arkisto', // headline
[...]

In library file /inc/library.inc, the translations file is first included:

    Include: $fromMetoRoot + 'languages/' + $lang + '.inc';

...and this tag ties together the page code and the translations file:

Define_Tag: 'str',-Required='str';
    Local:'output' = string;
        If: $lang == 'en';
            #output = #str;
        Else;
            if: $mTranslations -> (Find:#str);
                // for mTranslations, see lang file
                #output = $mTranslations -> (Find:#str);
                else;
                #output = #str;
            /if;
       /If;
    Return:#output;
/Define_Tag;

Case difference is not preserved, but so far I haven't had problems with
that. I have only had problems with syntactic differences among languages.
For example in English one says

    found_count; 'records were found';

...but in Finnish, the natural phrase is:

    'Löytyi'; found_count; 'tietuetta';

So, if the default lang is English, there's no way in this setup to get
'Löytyi' out from the language file, because an empty string cannot be a
key.

- Jussi

--
Jussi Hirvi * Green Spot
Topeliuksenkatu 15 C, 00250 Helsinki, Finland
Tel. & fax +358 9 493 981 * SMS +358 9 40 771 2098
[hidden email] * http://www.greenspot.fi



--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Pierre Yelle
Late on this thread...

Configs files are good , but keeping the language values in tables is  
also handy if you need to provide users with an interface in which  
they can alter/tweak the meanings.

Some one for example will like a field label to say
Function:

while another user might want to use

Function title:

You have the option to either read the whole table to build the lasso  
map on language switching;
  or copy all values (lg1, lg2, lg3,...) to a MEM engine table if you  
use MySQL .

The ctag that fetches the values can then look in the MEM or read from  
the Lasso map

Also if you do have application owners that operate different  
subsystems (banners for example), or multiple customers on a shared  
server,  it is easy to append a banner number to all values in the  
database and have the ctag first look for the value with the banner  
number before defaulting to the standard...

so the default for an interface label «Part Number» would be

part_number_00 = Part number / Numéro de pièce / Número de pieza

if the user of banner 7 wishes so,
he can duplicate the value and your application appends his banner  
number so that on his site will read:

part_number_07 = Part # / # de pièce / # de pieza




Tables are needed if users need to maintain product names and  
descriptions in all available languages.

I like to call those fields lg1 lg2 lg3 ...

Users select a language that is added to the session as lgNb = 1 or 2  
or 3 ...
... and the application can fetch the (field:'lg'$lNb)

I set a cookie or a pref in a user field.

You might want to consider having a master preference set once by the  
application owner as to how many languages he wishes to maintain and  
have the application show the lg1 lg2 lg3 ...  fields only if the  
master preferences warrants it.

HTH


Pierre






On 14-Aug-08, at 11:18 , Jussi Hirvi wrote:

> ...

--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Da'oud Rashid
In reply to this post by Jussi Hirvi
Hi Jussi,

Your approach is similar to the approach I use. I'm using a large  
global map variable, not a per-page var, however, as we're dealing  
with about 1200 individual strings (sometimes containing multiple  
paragraphs of text) and it doesn't make sense to load these into  
memory for each web page.

In terms of the problem with syntactical differences across languages,  
you can do this:

English String: '<found_count> were found'

Finnish String:  'Löytyi <found_count> tietuetta'

It is relatively easy to ask translators to place the <found_count>  
part in the appropriate place when they do the translation. For my  
system, each string has a optional note which provides contextual  
information to translators. This helps them understand how the  
translated sentence should be constructed. You can also do the  
following as well:

English String: 'This is text with a <link_location>link</a> embedded  
in it.'

With the above, your translator doesn't need to worry about lengthy <a  
href="..."> tags.

You can then use a simple [string_replace] to place the numbers (or  
references to links, day names, month names, etc) in the string:

[var_set:'temp_str'=(str: '<found_count> were found')]
[$temp_str->(replace: '<found_count>', (found_count))]
[$temp_str]

(as an aside, if you use -encodenone in [str:-encodenone, 'This is a  
<link>link</a>.'], the web browser will not display anything if <link>  
is not replaced with the actual link)

One problem I've found with the overall (global or var) Map approach  
is that multi-line strings are not always found using ->(find:'multi-
line string'). I think this is an issue when multiple platforms/
applications (with bugs in them) are being used when constructing and  
transferring the reference strings back and forth.

In my case, I found this issue occurred when using Mac OS X and  
FileMaker 8.5 (with FileMaker's Substitute function being directly  
responsible). Filemaker 8.5 (on Mac OS X 10.5.4) replaces either a  
carriage return or line feed with a weird space-type character (even  
though the substitute tag makes no reference to carriage return, line  
feed, or both together). When these strings are uploaded back to the  
server, they no longer match the reference string in the Lasso format  
files.

My solution was to ensure that decode_url:'%0D%0A' (carriage return  
and line feed) is always replaced by a single \r (carriage return)  
before transferring the strings from Lasso to FileMaker (when the  
strings are transferred back to Lasso, it has no issues finding them).

Before tracking down the bug, I replaced multi-line reference strings  
with one-line descriptive text (i.e. 'found_count_display_text'),  
which is more readable to than having the [str:] contain several  
paragraphs of text, anyway.

This approach, of course, requires that your default language is also  
placed in a Map variable.

As Pierre suggested, this in turn (along with your translations) can  
be stored in a database. In my case, the code for the Map variable is  
constructed from database tables and written to a file (which is then  
loaded into Lasso through an [include]...the file is also included  
when the Lasso site is started). I run this Map-construction code on  
an ad-hoc basis (usually, after multiple updates to the language  
strings). I expect you can write code that modifies only parts of the  
Map variable file, but I preferred to recreate the file in its entirety.

If you use a global variable, rather than including the variable on  
each web page, you can also replace reference strings and associated  
text instantly, by using:

->(remove:'OldReferenceValue') and -
 >(insert:'NewReferenceValue'='NewReferenceText')

After multiple changes, you can (and should) recreate your [include]d  
Map variable file, so that the changes are included if the site/server  
is restarted.

In the long run, building a Lasso-based interface for yourself and  
your translators (as Pierre also suggested) makes managing the strings  
a lot easier than manually editing localization files/variables, so  
it's well worth the effort. I should also note that I took my  
localization interface a step further by making it rewrite my lasso  
format files when reference text is changed (of course, you don't want  
your translators to be able to do that or modify the reference text;  
only yourself!). This saves a lot of time when dealing with 100s of  
files that can potentially contain your reference text.

I hope this helps!

Kind regards,
Da'oud

On Aug 14, 2008, at 7:18 PM, Jussi Hirvi wrote:

> I see the dye is cast already, but here's another approach to  
> localization.
> The good side is that the page code looks good and intuitive. And the
> translations file is easy to make. The bad side is that if the site is
> large, some conflicts may arise.
>
> In the LassoBlogger blogware I have used a system which was copied  
> from
> WordPress - I'm not sure if WP still uses this. LassoBlogger code is  
> easily
> available at http://www.lassoforge.com .
>
> In a config file is a language selector, like:
>    var:'lang' = 'fi';
>
> In the code every translatable text string is marked like this:
>    str:'Please give an email address';
>
> Str is a custom tag. Namespace (like "LB_") is omitted in the tag  
> name, to
> keep it short.
>
> Thus English is the default language (could as well be Norwegian).
>
> The actual translations are in /languages/fi.inc, where "fi" means  
> Finnish,
> in this case. The main part of that file is a long map, in  
> alphabetical
> order:
>
> var:'mTranslations' = (Map:
> 'A comment has been added to your blog at'      = 'Blogiisi on lisätty
> kommentti, ks.', // used in email message
> 'and start writing posts (if your initial permissions allow it)' = 'ja
> ryhtyä
> kirjoittamaan blogiviestejä (jos uudelle käyttäjälle myönnetyt  
> oikeudet
> sallivat tämän)', // use-registered.inc
> 'and your password' =  'ja salasanasi', // use-registered.inc
> 'Archives' = 'Arkisto', // headline
> [...]
>
> In library file /inc/library.inc, the translations file is first  
> included:
>
>    Include: $fromMetoRoot + 'languages/' + $lang + '.inc';
>
> ...and this tag ties together the page code and the translations file:
>
> Define_Tag: 'str',-Required='str';
>    Local:'output' = string;
>        If: $lang == 'en';
>            #output = #str;
>        Else;
>            if: $mTranslations -> (Find:#str);
>                // for mTranslations, see lang file
>                #output = $mTranslations -> (Find:#str);
>                else;
>                #output = #str;
>            /if;
>       /If;
>    Return:#output;
> /Define_Tag;
>
> Case difference is not preserved, but so far I haven't had problems  
> with
> that. I have only had problems with syntactic differences among  
> languages.
> For example in English one says
>
>    found_count; 'records were found';
>
> ...but in Finnish, the natural phrase is:
>
>    'Löytyi'; found_count; 'tietuetta';
>
> So, if the default lang is English, there's no way in this setup to  
> get
> 'Löytyi' out from the language file, because an empty string cannot  
> be a
> key.
>
> - Jussi
>
> --
> Jussi Hirvi * Green Spot
> Topeliuksenkatu 15 C, 00250 Helsinki, Finland
> Tel. & fax +358 9 493 981 * SMS +358 9 40 771 2098
> [hidden email] * http://www.greenspot.fi
>
>
>
> --
> This list is a free service of LassoSoft: http://www.LassoSoft.com/
> Search the list archives: http://www.ListSearch.com/Lasso/Browse/
> Manage your subscription: http://www.ListSearch.com/Lasso/
>


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Jussi Hirvi
Da'oud Rashid ([hidden email]) kirjoitteli (15.8.2008 02:50):
> Hi Jussi,
>
> Your approach is similar to the approach I use. I'm using a large
> global map variable, not a per-page var, however, as we're dealing
> with about 1200 individual strings (sometimes containing multiple
> paragraphs of text) and it doesn't make sense to load these into
> memory for each web page.

Da'oud,

Thanks for your comments. I will probably adapt your trick with the
[found_count] example.

I agree that it would be better to use a global (site-wide) var, but not all
LassoBlogger users have admin privileges to their Lasso site.

- Jussi

--
Jussi Hirvi * Green Spot
Topeliuksenkatu 15 C * 00250 Helsinki * Finland
Tel. & fax +358 9 493 981 * Mobile +358 40 771 2098 (only sms)
[hidden email] * http://www.greenspot.fi


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Da'oud Rashid
Hi Jussi,

Glad to be of assistance. I hope the ->(replace) trick works well for  
you!

Kind regards,
Da'oud


On Aug 15, 2008, at 9:52 AM, Jussi Hirvi wrote:

> Da'oud Rashid ([hidden email]) kirjoitteli (15.8.2008 02:50):
>> Hi Jussi,
>>
>> Your approach is similar to the approach I use. I'm using a large
>> global map variable, not a per-page var, however, as we're dealing
>> with about 1200 individual strings (sometimes containing multiple
>> paragraphs of text) and it doesn't make sense to load these into
>> memory for each web page.
>
> Da'oud,
>
> Thanks for your comments. I will probably adapt your trick with the
> [found_count] example.
>
> I agree that it would be better to use a global (site-wide) var, but  
> not all
> LassoBlogger users have admin privileges to their Lasso site.
>
> - Jussi
>
> --
> Jussi Hirvi * Green Spot
> Topeliuksenkatu 15 C * 00250 Helsinki * Finland
> Tel. & fax +358 9 493 981 * Mobile +358 40 771 2098 (only sms)
> [hidden email] * http://www.greenspot.fi
>
>
> --
> This list is a free service of LassoSoft: http://www.LassoSoft.com/
> Search the list archives: http://www.ListSearch.com/Lasso/Browse/
> Manage your subscription: http://www.ListSearch.com/Lasso/
>


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

dguardiola
In reply to this post by Pierre Yelle

Le 14 août 08 à 23:08, Pierre Yelle a écrit :
>
> You have the option to either read the whole table to build the  
> lasso map on language switching;
> or copy all values (lg1, lg2, lg3,...) to a MEM engine table if you  
> use MySQL .
>
> The ctag that fetches the values can then look in the MEM or read  
> from the Lasso map

Please Pierre,
this is totally unknown to me : does this kind of SQL type of DB will  
use less RAM than these mega-lasso-maps which are eating my mini's RAM ?
Or will it be the same ?

Dominique Guardiola
--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Lars A. Gundersen-2
In reply to this post by Fletcher Sandbeck-3
Hi,

I just wanted to followup on thi, detailing what I ended up doing.
I took the advice to put all the text strings for one language into a  
simple text file. Line 1 is the key, line 2 is the text for the key in  
the language for that file, line three new key etc. This way it's very  
simple to ask people to translate, no special file format that they  
have to use. Just send them the text files, explain that they should  
only alter lines with even line numbers etc. And when you get the file  
back, just check it for line number consistency and dump it in place.
The files are called en.txt, no.txt, se.txt etc.

Ok, so the code to read the file is in a startup script for the site:

<?LassoScript
        var('langStrings') = map;
        Global('langDefault') = 'no';
       
        Var: 'langDir' = File_ListDirectory: '///path/to/language/directory/
where/language/files/reside/';
        var: 'langName', 'filePath';
        var: 'langMap' = Map;
        Loop: $langDir->Size;  // for each language file
                If: $langDir->(Get: Loop_Count) >> '.txt';
                        $langName = $langDir->(Get: Loop_Count);
                        $langName->(RemoveTrailing: '.txt');
                        $filePath = $langDir + $langName + '.txt';
                        // put each (key=text string) pair into a map
                        Loop: (File_GetLineCount: $filePath), -By=2;
                                $langMap->(Insert: (File_ReadLine: $filePath, -
FileLineNumber=(LoopCount)) = (File_ReadLine: $filePath, -
FileLineNumber=(LoopCount+1)));
                                /Loop;
                        // then put the map with the text strings into a map which will  
contain all strings in all supported languages
                        $langStrings->(Insert: $langName=$langMap);
                /If;
        /Loop;
?>

A thing to note here is that since the code is in the site's startup  
script, you have to use an absolute path from the file system's root.  
And you have to put that specific path into the file permission  
section in Lasso server admin and site admin. My foler was inside my  
normal site folder, but it didn't help that I had sat the correct file  
permissions for folders relative to the site's root.

To use this map, I implemented Fletcher's ctag suggestion, also in the  
startup script:

<?LassoScript
        define_tag('localize', -required='key', -optional='lang');
                Local('result');
                !local_defined('lang') ? local('lang') =  
if_empty(Global('langDefault'), 'no');
                local('map') = $langStrings->find(#lang);
                #result = #map->find(#key);
                #result ? return(#result) | return('<span class="warning">Internal:  
no localized string found.</span>');
        /define_tag;
?>

In my lasso pages, I then call it like this:
.
.
<p class="rightpad">[Output: Localize('front_text4', -lang=$lang), -
encodeNone]</p>
.
.


front_text4 is a key, and $lang is a session variable, containing 'no'  
or 'en' etc, depending on which language is served to the user. Some  
strings contain html, so I have to use -encodeNone.

A concern with this is speed. The building of the language map is only  
done when the site starts, so it is not critical. However, the ctag  
can be called very many times per page, so it needs to be as optimized  
as possible. Indeed, a critical page in the survey webapp I use this  
for calls it over 150 times, and it took over 3.5 seconds to process.
I therefore shaved it a little bit:

<?LassoScript
        define_tag('localize', -required='key', -optional='lang');
                Local('result');
                !local_defined('lang') ? local('lang') = Global('langDefault');
                #result = ($langStrings->find(#lang))->find(#key);
                #result ? return(#result) | return('Error: no localized string  
found.');
        /define_tag;
?>

Getting rid of the local map variable had has an appearant effect a  
tremendous speedup, and the page is now served in just under 0.5  
seconds.

If anyone can see any way to optimize the ctag any further, please let  
me know.

Lars
--
Lars A. Gundersen
http://www.larsagundersen.no/ • +47 91 64 46 10


--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/

Reply | Threaded
Open this post in threaded view
|

Re: Localizing a webapp

Johan Solve
On Wed, Nov 26, 2008 at 12:32 AM, Lars A. Gundersen
<[hidden email]> wrote:
> Getting rid of the local map variable had has an appearant effect a
> tremendous speedup, and the page is now served in just under 0.5 seconds.

You would probably get a similar performance improvement by changing
to local map variable to a reference instead of a copy:

               local('map') = @($langStrings->find(#lang));

It would not be better than your last version so this is just a purely
academic observation.

--
Mvh
Johan Sölve
____________________________________
Montania System AB
Halmstad   Stockholm   Malmö
http://www.montania.se

Johan Sölve
Mobil +46 709-51 55 70
[hidden email]

Kristinebergsvägen 17, S-302 41 Halmstad, Sweden
Telefon +46 35-136800 |  Fax +46 35-136801

--
This list is a free service of LassoSoft: http://www.LassoSoft.com/
Search the list archives: http://www.ListSearch.com/Lasso/Browse/
Manage your subscription: http://www.ListSearch.com/Lasso/