[SOLVED] Dynamic Multi-lingual

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
LANSAGuru
Posts: 69
Joined: Thu Mar 24, 2016 5:31 am

[SOLVED] Dynamic Multi-lingual

Post by LANSAGuru »

Multilingual variables get burned into a compiled program.
I have a use case where a set of menu's is loaded dynamically from a file.
The file will have menu option and a description, but I want the description to be multilingual value.
So I want to put the name of the multilingual variable into the file and use it at runtime.

So I would have

#label.caption := multilingual_value_of(#field from file)

Currently I need to add a case statement for each new menu option to extract the appropriate multilingual variable which is a not elegant.

Concurrently, this same capability would be interesting to use against repository fields.
e.g.
#lbl_Logged_Date_Time := #itlogd.FieldAttributeAsString( Description ) if the field itself (#ITLOGD in this example) were also set able at runtime dynamically, but I don't think that would be a as common a use case. Due to layout issues for responsive design, I had to use labels vs. the default labels for fields in some cases, and this was a way to use the repository values instead of hard coding them and preserving the inbuilt multi-lingual capabilities of the repository.

The difference here is I don't know ahead of time which menu item or multilingual variable will be read from the file.

Is this possible?

Edit:

I thought of this.
The file will contain the name of a field in the repository.
The repository field will contain the multilingual descriptions needed.
At runtime we create a new field object like so

Set_Ref Com(#Result) To(*CREATE_FROM #The_Field.Value.Trim)

Then we set the properties to suppress the input field and only show the description of the field.

This will work (I think), but a bit of a kludge. Hoping for something more elegant. I really want to use the power of multi-lingual variables here, but in a dynamic way.
MarkD
Posts: 692
Joined: Wed Dec 02, 2015 9:56 am

Re: Dynamic Multi-lingual

Post by MarkD »

In VLF-ONE we use a technique like this:

We have singleton scope(*Application) system manager called #USystem and it has a PRIM_KCOL named uMtxtValues of Unicode strings that has getter and setter methods, like this:

Code: Select all

* -----------------------------------------------------------------------------------
* Keyed collection to store Multilingual text strings
Define_Com Class(#PRIM_KCOL<#Prim_dc.UnicodeString #VF_ELSYMNAME>) Name(#MultilingualTextValues) Style(Collection)
Define_Pty Name(uMTxtValues) Get(Get_MtxtValue) Set(Set_MtxtValue)
* -----------------------------------------------------------------------------------
Ptyroutine Name(Set_MtxtValue)
Define_Map For(*input) Class(#prim_dc.UnicodeString) Name(#MultilingualTextValue)
Define_Map For(*input) Class(#VF_ELSYMNAME) Name(#MtxtKey)
Define_Com Class(#prim_dc.UnicodeString) Name(#MultilingualTextValueReference) Reference(*DYNAMIC)
#MtxtKey := #MtxtKey.UpperCase
#MultilingualTextValueReference <= #MultilingualTextValues<#MtxtKey>
If (#MultilingualTextValueReference *Is *null)
Set_Ref Com(#MultilingualTextValueReference) To(*Create_as #prim_dc.UnicodeString)
#MultilingualTextValues<#MtxtKey> <= #MultilingualTextValueReference
Endif
#MultilingualTextValueReference.Value := #MultilingualTextValue.Value
Endroutine

* -----------------------------------------------------------------------------------
Ptyroutine Name(Get_MtxtValue)
Define_Map For(*OUTPUT) Class(#prim_dc.UnicodeString) Name(#MultilingualTextValue)
Define_Map For(*input) Class(#VF_ELSYMNAME) Name(#MtxtKey)
Define_Com Class(#prim_dc.UnicodeString) Name(#MultilingualTextValueReference) Reference(*DYNAMIC)
#MtxtKey := #MtxtKey.UpperCase
#MultilingualTextValueReference <= #MultilingualTextValues<#MtxtKey>
If (#MultilingualTextValueReference *IsNot *null)
#MultilingualTextValue := #MultilingualTextValueReference
Else
* Convert an MTXT reference. NOTE: This is recursive !!!!!
If (#MtxtKey.Substring( 1 5 ).UpperCase = 'MTXT=')
#MultilingualTextValue := #COM_OWNER.zInt_HandleMTXTMessage( #MultilingualTextValue )
Else
#MultilingualTextValue := "No MTXT=" + #MtxtKey
Endif
Endif
Endroutine
At start up time we run a snap in program named UF_OMULTI that loads up the dynamic MTxt collection like this:

Code: Select all

#uSystem.uMTxtValues<Top> := *Mtxtuf_Top
#uSystem.uMTxtValues<Bottom> := *Mtxtuf_Bottom
#uSystem.uMTxtValues<Maximize> := *MTXTUF_MAXIMIZE
#uSystem.uMTxtValues<Minimize> := *MTXTUF_Minimize
#uSystem.uMTxtValues<Restore> := *MTXTUF_Restore
All other code references the MTXTs indirectly by their assigned symbolic name, for example:

Code: Select all

#RestoreImage.Hint := #USystem.uMTxtValues<Restore>

#Button.Caption := #USystem.uMTxtValues<Maximize>
This has several advantages:
- If a customer changes any *MTXT’s value they just need to recompile UF_OMULTI
- If a customer is dealing in a language that we do not ship, say Portuguese, they can even just use literals into UF_OMULTI.

I think, but am not sure, that this model might fit your requirement because the source of the strings at load up time can be from anywhere.
MarkD
Posts: 692
Joined: Wed Dec 02, 2015 9:56 am

Re: Dynamic Multi-lingual

Post by MarkD »

BTW - this bit of code:

* Convert an MTXT reference. NOTE: This is recursive !!!!!
If (#MtxtKey.Substring( 1 5 ).UpperCase = 'MTXT=') etc ............

is so that server side applications can send back multilingual messages.
The server sends MESSAGE("MTXT=RESTORE") and that gets converted to the <RESTORE> multilingual message.
User avatar
Stewart Marshall
Posts: 417
Joined: Thu Nov 05, 2015 5:25 pm

Re: Dynamic Multi-lingual

Post by Stewart Marshall »

LANSAGuru wrote: Tue Aug 29, 2017 1:23 am I really want to use the power of multi-lingual variables here, but in a dynamic way.
Sadly, multilingual variables and field multilingual features aren't dynamic.

The simplest solution is to add a language key to the table. If for some reason you really don't want to change the table definition, leave the table as is for your default language, and add a second table for additional languages.

Your problems would be solved with a single IF/ELSE.
Stewart Marshall

Independent IT Consultant
www.marshallfloyd.com.au
LANSAGuru
Posts: 69
Joined: Thu Mar 24, 2016 5:31 am

Re: Dynamic Multi-lingual

Post by LANSAGuru »

Thanks all for the responses.

Conclusions:

1. Dynamically getting the value of an arbitrary multi-lingual variable at run time is not possible.

2. An approach like the VLF is using will work to solve the problem.
Post Reply