Use the text attribute (or similar) of an identifier to automatically set a "pretty name" in WebUI

Related products: WebUI
  • 6 November 2019

We can of course modify the <model name>.properties file in ~\MainProject\WebUI\resources, but as this is a feature which we probably want for all parameters shown in the WebUI, could this be made more developer-friendly? This would also resolve that we have to update the .properties file when we changed the name of an identifier. 

Perhaps this could even be done in such a way that we could use string parameters for this “pretty name” which allows them to change dynamically. In this case, I think we don't want to be forced to use string parameters (as this would result in a lot of additional parameters), but we should be able to also use a static string.

You can put this in a procedure and run it on project initialization or termination:

 


If ProjectDeveloperMode Then

put tmpTranslationFile;

for IndexIdentifiers | IndexIdentifiers.txt do

put IndexIdentifiers + " = " + IndexIdentifiers.txt + "\n";

endfor;

putclose;

EndIf:


 


Thanks for your quick reply Sander, this works great! I played around with it and it is working for static texts. Would you also have an idea about if / how we could use string parameters for the same purpose?

Anyway, this is of great help and will help us structure the translations way better. Thanks!


I don't think the WebUI supports dynamic TranslationProperties right now. To get similar behaviour, you could maybe restructure your index domains and make clever use of ElementText, or by decoupling the WebUI parameters from your datamodel and write procedures to fill the WebUI parameters dynamically.


@sandervlot Okay, that sounds like an option. However, in almost all cases, static translations suffice :smile: . Happy with this solution!


You can extend this option to multi-language support (e.g. asked by @mateusarakawa or @Imke) by adding a StringParameter over AllIdentifiers (or some of them as not all are displayed) as the txt-property does only offer the info from the text attribute of an identifier and thus is limited to 1 string.

Extending your App UI then with e.g. a DialogPage to select a language (after which a translation file is generated), and even using the new status bar that is in beta (available here) to give a clear indication of current language and ability to change, you can easily switch. Of course, instead of generating this each time, you can also prep translation files and switch those out. 

I added a video in the folder above on the example below in picture and a text-excerpt of the Story Delivery model extension I created to translate a small piece of the UI (multi-language.txt). Also added a simple example in this post for your reference that runs in regular recent AIMMS versions without fancy status bar items and dialog pages (just rename TranslationProject.txt to TranslationProject.7z after downloading).

 

NOTE: Under AIMMS PRO/AIMMS Cloud, you have to do a “Empty Cache and Hard Reload” of the browser after the new translation file was created (i.e. after a new language is selected in this example); in develop, a refresh of the browser is sufficient. I recognize this can be better, but it might already help you as well and and enables you to be more dynamic.

Going from English to Dutch (Dialog is activated from Status Bar item ‘Language’)

 

After selecting Dutch, a few selected parts have been translated​

 


BTW: After some internal discussions, I would not suggest making adjustment of the translation files on the fly; it is even doubtful whether we should allow this. Best to have static files available and decide before starting up what language to show (so eg in MainInitialization). This way, you do not have any of the run-time or cache issues. 


E.g.  

switch (SelectedLanguage) do

'English': FileCopy("MainProject/WebUI/resources/translate_en-us.txt",
"MainProject/WebUI/resources/translate.properties");

'Dutch' : FileCopy("MainProject/WebUI/resources/translate_nl.txt",
"MainProject/WebUI/resources/translate.properties");

default : ! nothing

endswitch;

 


Thank you, @Gertjan! Happy to see the options which help in this need.


What annoys me is the inability to use different “pretty” names for different widgets. For example I may want to use “Customer” in one widget and “Client” in another. 

This is a trivial example, but I have run into non-trivial situations where I do indeed need to display different labels in different widgets. 

BTW, you CAN do this in WinUI - which makes is more annoying when trying to switch a current app from WinUI to WebUI. 


Thanks for sharing @MathFour , I assume you refer to the same identifier being labeled as “Customer” in widget 1 and “Client” in another widget.

I am aware this is possible in WinUI and yes it could be nice to be able to do this ‘inside’ the widget (like being able to change the title of a widget, change the header of an identifier such that you do not have to see identifier names itself).  

If I may, I do wonder however if this is a good practice (to have two different labels for the same) as this can also lead to confusion. In your example (and understand there are others), I am suspecting there is no standard definition of the companies that buy products being ‘clients’ (typically in consulting business) or ‘customers’ (typically in commodity business), hence both exist and are mixed, or different users build different parts over time and suggested a different label. I would therefore choose one or the other and be consistent throughout.

Possibly your non-trivial examples could help me. Can you share?


Hi @Gertjan, I have one example which I ran into recently. I had a table to penalize movements between zones, handled by a parameter P_ZonePenalty(i_zone, j_zone) where i_zone and j_zone are indices of the set S_Zones.

In the UI, I explicitly wanted to display the "Zone from” and "Zone to”, because not all transitions were possible, the penalties were non-symmetric. However, the WebUI would only show the translation of S_Zones if I were to use i_zone and j_zone (in a table widget, that is). I fixed this by creating copies (being subsets) of the set S_Zones: S_ZonesTo (index i_zoneTo), S_ZonesFrom (index i_zoneFrom), which I could translate differently. Then, in my table, I would display P_ZonePenalty(i_zoneFrom, i_zoneTo).


Nice example, @Richard, I had a similar one with location to and from. 

The other non-trivial example, @Gertjan, is due to another workaround that I’ve had to do because WebUI doesn’t have automatic legends/keys for line graphs. 

Suppose I have a line for current inventory (p_cur_inv) that is blue and dashed and a line for minimum inventory (p_min_inv) that is blue and solid. At the same time I have a table with these two as columns.

As you know, we have to“hack” the legend widget to be the legend/key for a linechart. So we can only show the color. 

Thus, for the table I want

p_cur_inv = Current Inventory
p_min_inv = Minimum Inventory

And for the legend I want

p_cur_inv = Current Inventory - dashed line
p_min_inv = Minimum Inventory - solid line

This is not only an example, but also support for the suggestion to give us a built in legend/key for line and bar charts.


Didn't find what you were looking for? Try searching on our documentation pages:

AIMMS Developer & PRO | AIMMS How-To | AIMMS SC Navigator