[jsword-devel] I18N

Troy A. Griffitts jsword-devel@crosswire.org
Sat, 27 Dec 2003 13:00:12 -0700


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