[jsword-devel] I18N
Joe Walker
jsword-devel@crosswire.org
Mon, 29 Dec 2003 23:06:16 +0000
Andy - this is well worth reading - JSword does something very similar
in looking up strings.
The one difference is that where Sword uses "const char*" as the type to
look up JSword has a "static final Msg" which lets us add type safety in
some places.
So JSword code looks like this:
throw new BlahException(Msg.WRITE_FAIL);
Note you can't throw unless you take note of I18N. This is not a system
for sloppy programmers.
And in the local Msg class
static final Msg WRITE_FAIL = new Msg("Failed to write");
And in the French resource file:
Failed to read=N'ecrire pas
(or something)
Hope this helps.
Joe.
Troy A. Griffitts wrote:
> Hey guys. I also had a tough time deciding how to handle i18n in the
> windows frontend. As well, we are building an i18n mechanism for our
> website. Here are some of my thoughts.
>
> I agree 100% that I hate keeping string files up to date. I hate
> looking at DEFINE_TOKENS instead of the actual string, and I hate going
> somewhere to have to change the string other than right where I'm at in
> the code.
>
> Here was my solution in the Windows client: Since Borland's VCL GUI
> classes provide programmatic methods to change all the 'Caption' or
> 'Text' properties of a control, we have 1 function called i12ize(const
> char *lang), which is where all the stupid monolithic calls to EVERY
> control exist to change it's text. There are also classes in the SWORD
> engine called SWLocale and LocaleMgr which manage locales and do simple
> lookups from a basic .conf file formatted like:
>
> My English Text=My Alternate Language Text
>
> Here are excerpts from the code:
>
> ____________________
>
> #define _tr(text) LocaleMgr::systemLocaleMgr.translate(text)
>
> void TForm1::i12ize(const char *lang) {
> LocaleMgr::systemLocaleMgr.setDefaultLocaleName(lang);
>
> File1->Caption = _tr("&File");
> SaveLayout1->Caption = _tr("S&ave Layout");
> Print1->Caption = _tr("&Print...");
> ...
> ____________________
>
> translate() looks up the English phrase in the current locale.conf file,
> and returns the translation, if it finds it; otherwise, it just returns
> back the English phrase.
>
> Benefits:
>
> o You can code normally, without worrying about i18n.
> o Worst case is the English will show up on the control
> o And my favourite part: You can declare, "This is an open source
> project! If you want your language supported, then test it, look for
> english strings, and update your lang.conf file!"
>
> Those lines should probably be changed to:
> - File1->Caption = _tr("&File");
> + File1->Caption = _tr(File1->Caption);
>
> And better yet a programmatic walk of the control tree, instead of
> naming each control individually, would be IDEAL.
>
> ____
>
> For the web interface, we're working on a taglib that adds functionality
> like:
>
> <table>
> <tr><td><t>My text</t></td></tr>
> </table>
>
> (Example above, set in a table to just show that it's not extremely
> intrusive)
>
> The <t> tag does a lookup and replace of the string in much the same way
> as LocaleMgr. It will also allow someone to log in as an admin, set a
> session variable admin to true, then a link at the bottom of each page
> will appear that says: Administrate I18n
>
> While browsing the website, if an administrator sees an English word,
> they may click this link, and be taken to a page where they are
> presented with all the <t>English Text Strings</t> and the existing
> translations, and are able to update any that are wrong or missing.
>
> Benefits: It only has one evil tag addition, <t> around all text, and
> still allows me to make the coveted Open Source Declaration mentioned
> above.
>
> :)
>
> Hope this, at least, gives some ideas to throw around from someone who's
> struggling with the same issues.
>
> -Troy.
>
>
>
>
> Joe Walker wrote:
>
>>
>> JSword used to use a method very similar to yours, and I found that
>> the message file was constantly getting out of date with respect to
>> the source.
>> There were 3 problems:
>> - editing properties files was a hassle
>> - unused messages would not be purged
>> - lazy developers (me!) would add an i18n key thinking "i'll add it to
>> the message file later" and never do it.
>>
>> The Msg system solves these problems by making the I18N type-safe -
>> Exceptions take a Msg and not a String and so on.
>>
>> You can now navigate to the message with a single key press in any
>> decent IDE (in eclipse I just press F3)
>> You can detect if the message is used without lengthy search
>> procedures with your IDE (ctrl+shift+g in eclipse)
>> The english developer can ignore message files completely because the
>> messages are in the source
>> JSword can sill be internationalized simply by adding message files
>>
>> To clear up some of the points you made:
>> Does this scheme waste space?
>> We use extra static space for a few objects that wrap strings. Only
>> one copy of MsgBase is needed, and the strings themselves (the things
>> that take up the real space) would exist anyway.
>> So yes this does waste some space, but I think that is a reasonable
>> price to pay.
>>
>> Joe.
>>
>>
>> _______________________________________________
>> jsword-devel mailing list
>> jsword-devel@crosswire.org
>> http://www.crosswire.org/mailman/listinfo/jsword-devel
>
>
> _______________________________________________
> jsword-devel mailing list
> jsword-devel@crosswire.org
> http://www.crosswire.org/mailman/listinfo/jsword-devel