Contact Information

Chris Toohey

Like what you see? Help feed-the-beast by donating to the site and it's humbly thankful author!

My Twitpic Updates
    Site Resources

    RSS Site Content
    Syndicate This Site!
    DG Banner Logo
    Advertisements

    IBM Lotus Notes and Domino 7 now available

    Poll: How many of us need to develop multilingual UIs for our Lotus Notes and/or Domino Applications?

    09/17/2008 11:35:23 AM | Chris Toohey | Bethlehem, PA

    My current 40+ Hours/Week Customer happens to be a larger and globally dispersed Notes Shop. In my going-on-two-years with this customer, I have yet to have a project where one of the requirements were multilingual user interfaces for a given Lotus Notes or Domino Application. Now, there are applications that span multiple countries and regions... but we've always just gone with English-based UIs.

    So... do you have to deal with supporting multiple languages in your Lotus Notes and/or Domino Applications? If so, what is your preferred method?

    I'll share mine once/if we get a few answers, and you can leave your answer in the comments section - but I'll give you a quick preview:

    For Lotus Notes Client Applications:

    For Forms this is easy - a simple hidden field that renders a key:translation paired list of all defined translations. Then, each UI component does a lookup to that field and renders the translation.

    The problem I've run into in the past is Views - specifically View Columns...

    For Domino / Browser Client Applications:

    I tend to "roll my own", so this really isn't a problem. Forms are handled the same way, as are Views: I typically have my markup View tables render without headers and footers, which I add via Computed Subform logic in the ViewTemplate for my particular View.

    I will elaborate more on this in the follow-up article...


    Like what you see? Help feed-the-beast by donating to the site and it's humbly thankful author!

    Comments

    Theo Heselmans
    http://blog.xceed.be
    09/17/2008 01:32:30 PM

    I do the same for forms (2 lists: code for doing @member to get position, translation list for getting translation using []). I let the (power)user enter the translations, 1 doc for each translation. And save the lists (code + 1 field for each language) in a profile doc, for faster access on a form. I use the same profile info for looking up translations for e.g. scripts/agents, outlines, action buttons, ....

    View titles remains a pain. I (and I'm not alone) have been begging for years, at each LS to make view titles computed (like action buttons). To no avail. My customers usually agreed to settle for a 'common' language (e.g. English) for the view titles. Annoying !

    A tip for form translations: I use e.g. a computed for display field called 'xPhone', and use @thisname to create a label based on the fieldname after 'x'. This way, you can create labels using the same formula everywhere. You just need to change the name for the field.

    Looking forward for your follow-up article.


    John Smart
    www.greyduck.com
    09/17/2008 05:14:06 PM

    Multi-lingual forms are really great, but they only got me so far. There are still messageboxes, errors, status values, etc. I've found good luck with having all LotusScript being language independent except for a "Language-Dependent Globals" script library per language containing:

    • A function libfstrTranslateErrNum that's just a huge case statement converting custom error numbers into language-specific text
    • Other functions that convert statuses (stored as integers) into text
    • all other strings constants
    • Const libcstrStringSeparator = "|"

    So, let's say we're using my English script library, and calling libfstrTranslateErrNum(ciErrConfigDbNotOpen) returns "Could not find the configuration database. (Expected at | - |)"

    In that case the following code... (and please excuse the inconsistent method naming standards...)

    Public Function GetConfigDb(dbThis as NotesDatabase) As NotesDatabase
    	Dim astrPath(1) As String
    
    	astrPath(0) = dbThis.Server
    	astrPath(1) = "myapp/config.nsf"
    	Set GetConfigDb = New NotesDatabase(astrPath(0), astrPath(1))
    	If Not GetConfigDb.IsOpen Then Call ThrowCustomError(ciErrConfigDbNotOpen, astrPath)
    End Function
    
    Public Sub ThrowCustomError(iError As Integer, vArgs)
    	Error iError, libfstrMixIn(libfstrTranslateErrNum(iError), vArgs) 
    End Sub
    
    Public Function libfstrMixin(str1 As String, astr2) As String
    %REM
    Performs equivalent of @Implode(astr1 + astr2; "") if astr1 and astr2 are arrays with the same number of elements
    %END REM
    	Dim astr1 As Variant
    	Dim i As Integer
    	Dim u1 As Integer
    	Dim u2 As Integer
    	
    	astr1 = Split(str1, libcstrStringSeparator)
    	If Ubound(astr1) = 0 Then
    		libfstrMixin = str1
    	Elseif Isarray(astr2) Then
    		u1 = Ubound(astr1)
    		u2 = Ubound(astr2)
    		
    		If u2 >= u1 Then
    			For i = 0 To u1
    				libfstrMixin = libfstrMixin + astr1(i) + astr2(i)
    			Next
    		Else
    			For i = 0 To u2
    				libfstrMixin = libfstrMixin + astr1(i) + astr2(i)
    			Next
    			For i = u2 + 1 To u1
    				libfstrMixin = libfstrMixin + astr1(i)
    			Next
    		End If
    	Else
    		libfstrMixin = astr1(0) & astr2
    		For i = 1 To Ubound(astr1)
    			libfstrMixin = libfstrMixin + astr1(i)
    		Next
    	End If
    End Function

    If the config db wasn't where it was expected, GetConfigDb would throw an error where Error$ is Could not find the configuration database. (Expected at Server1/Org - myapp/config.nsf)

    But with someone in Japan, they'd have loaded the "Language-Dependent Globals" that's tagged as Japanese and so the message would be in their language.

    Using the same libfstrMixin function, I have an activity log at the bottom of documents that is, internally, all numbers and context arguments (i.e. who, when, etc) but is converted and displayed into the user's language at PostOpen.

    The really nasty part is keeping it all straight because now you've got several strings you can't forget at design time. 98% of my "Language-Dependent Globals" libraries' code is generated using a spreadsheet containing all of my constants and strings in a central location. I have a column for the constant name, numeric value, strings for each language, and then other columns that have concatenated it into LotusScript code that I can cut & paste into the appropriate script library. If I need to translate into another language, I just need to spin up another few columns and add the language strings and I'm already more than halfway done.

    I also use the event binding techniques Tim Tripcony recently blogged about so that I have one script library per form and each language's form's PostOpen is like "Set oForm = New MainDocumentFormCode(Source)" and then let the class constructor bind itself to the other form events.


    Darko Aleksic
    09/18/2008 05:50:28 AM

    Does anyone use Global Workbench for translating and generating multilingual databases?


    Vitor Pereira
    http://www.vitor-pereira.com
    09/18/2008 05:39:34 PM

    Did any of you ever tried setting a database as a 'Multilingual Database' and creating multilingual design elements? I think that could solve the view column titles problem but it means you must have a set of views for every language.


    Doreen
    10/29/2008 03:23:18 PM

    I anxiously await a solution. My biggest area of concern are input validation formulas. Thanks.



    Add a New Comment


    (Not Published/Public)
    Remember my Information!

    (Enter the text from the image to proceed)

    (Full markup allowed in the comment field below; play nice!)

    Live Comments Preview