Multi language

hi guys

Do you have plan for multi language?

Plans yes, but undecided on the how and the extent.

Here’s my take on a generic Multi Lingual class diagram with unlimited number of languages and strings, including user defined strings. String id:s are strings, preferably “human readable” (especially if user strings are to be supported).

Used in a sharp commercial business software. Usage:

string s = AppKernel.BusinessDomains.LingualDomain.GetMLString(“en”, “btn.cancel”);

Three levels of “multi language” strings in the system utilizing these classes:

  1. The language of the onlogged user (Forms and Messages).
  2. The language of intended recipient of printed documents (including user translations padded on to the “system” string & id lists).
  3. Hardcoded core - Kernel access only, defaults to English (or “RootLanguage”) as a “last resort” when/where none of §1 or §2 applies (“dev/sysadmin & “You’re not supposed to get this error” messages”-kind of situations).

I have not studied any developer platform ML systems after I modelled this, which was long before any such tools was supported by dev tools or by their plugins.

// Rolf

PS: The strange (M) symbols indicate some missing model modules, this ol’ Rose model was difficult to kick back to life for this screenshot.

ML diagrams are not my forte (someone once tried to teach me how to program with them, but they were unsuccessful in their endeavours).

Certainly a localised string should support any number of languages, and the user should be able to specify a fallback cascade; “I’d like to see Portuguese if at all possible, but if that’s missing then show me the Spanish string, after that the French one and after that the English one and after that I no longer care”. Which of course might mean that you end up seeing either Russian or German if no other translation is available.

Another thing to consider is that multiple people will be working on translations simultaneously with each other and simultaneous with the development of the software itself. So it needs to be easy to (a) add version control to the process and (b) see which strings haven’t been translated yet or need adjusting. This is an issue I haven’t really thought about yet. Clearly we already have a solution for this in Rhino itself, but I don’t know how it works.

I also would very much like the UI language to be a setting that is modifiable during runtime. Having to restart after switching to Italian sounds like a major drag.

There are however big problems with localisation if strings are composed programmatically, as so many are in Grasshopper. Different languages have different kinds of plurals, or genders, or other idiosyncrasies that ought to be taken into account when composing strings in code based on the runtime state. It almost sounds as though you would have to be able to provide a code snippet for string interpolation rather than just a dumb string.

I’ve spend a fairly significant amount of time already writing English language functions for plurals (-s, -es, -oes, -æ), articles (a, an), ordinals and cardinals (first, 23rd, twelve), etc. so whenever any of those are used in string interpolation, translating that text will be a lot of work.

Multiple developers
Excel sheets. New language = new column = easy to see if a single string (or language) is missing. And a macro doing unique checks. Then update the database from there only replacing strings with the same string-ID. Worked like that for years on a big project. And nowadays Excel sheets can have multiple users entering strings.

Fallback language
Using “string-id:s” you can even skip the final (root)string during development, if you do like we did - max 255 chars, and the string-id being essentially the same as the final English string (plus some category prefixes to make it easier to sort and also for other developers to find and reuse existing strings in tables when doing the translations, like “dlg.title.editbox”, or “btn.dlg.editbox.apply” if a string needs to be dialog specific (couldn’t come up with an example here but you get the idea)). If no “final string” was entered into the string database then the ultimate fallback “language” is - it follows - no language at all, that is, the id-string itself! :wink:

Ugly, but workx
I had these rules to make sure development wasn’t hampered by pondering on strings when a more complex conceptual problem was dealt with, just type in the id-string in your code and take care of the final natural strings some time later. The system would still give meningfull messages although an id-string would often look a bit ugly.

Runtime modifiable
Of course language should be modifieable during runtime (for example, one would show Dimension texts and other visible strings in the Designer’s own preferred language and - if drawing and sharing printouts for a foreign customer - modify the “object output” language so that any text on drawings are updated in rumtime (this is what my system does for invoices, notifications, forwarding documents, and well, any external documents)

As a matter of fact, my system had yet another level of language response; User’s “native language” for messages and help-system, while “UI-language” could be different. The two could be modified at logon (and in runtime of course). So there were a total of 4 “levels” on which strings were provided. Logging and other strings “deep in the kernel” with performance requirements would always use root language (or sometimes just the string-id, but that’s only for the “you’re not supposed to get this error” kind of messages).

Composable strings are no problem. The developer knowing that the string has place holders simply provide with the right number of strings and for the GetMLString(getUILanguage, “bt.ask.question”) to fill in.

And the final string “bt.ask.question” may look like:

  • “Hi {0}, although being early in the morning ({1} eh?) you still should consider providing a tolerance of at least 1 {2} if you expect this command to work”.

The developer adds a list or array with the three string-bits, like
fillstr[0] = GetUserName;
fillstr[1] = GetLocalTime;
fillstr[2] = GetMLString(getUILanguage; “system.units.” + Somehow.GetDocumentUnits());

And as expected, an override GetMLString method takes these extra strings and fills them in:

GetMLString(getUILanguage, “bt.ask.question”, fillstr);

Shouldn’t be a problem. Already did that. Works like a charm.

Functions for plurals
Nah, complete strings for all messages. That goes for the ordinals was well, and of course any single words being used. And nested GetMLString(…) to compose the final strings. There’s no way around that, but it works fine.

Wordy?

List of words becoming long? Well, don’t use so many words then. :wink:

// Rolf

Regarding UML diagrams and programming, this diagram is actually part of the runtime since everything except the method bodies is code-generated directly from the diagrams, and the diagram itself is embedded into the executable (for a kind of “model reflection” enabling the use of OCL string expressions to access objets in the object structure). All list relations automagically hashed and persisted, etc, etc.

I think Entity Framework is something in the same ball park but far from as capable as the platform I used.

One main benefit of Model Driven Architectures (MDA) is that there is no such thing as “free interpretation” of what a diagram actually means. The UML model is not only for documentation, instead the model actually IS the system. MDA/MDD/DDD simply works.

// Rolf

I wonder how that would change people describing their Grasshopper problems in this forum. A lot of grasshopper related questions are already a good mix between “too lazy to search with google” and “please do my work”- requests.:neutral_face: You could top that, if people throwing in the Hungarian equivalent of “loft”. :rofl: What a mess would that be… In my opinion I believe before learning how to read UML diagrams, you should all learn to speak German. That would make life much easier for me. :wink:
No seriously, I think this is a bad idea. Your coding language is in English, your president speaks English and even your breakfast is English. So learning English definitely helps people mastering their lives, and opens up a world full of knowledge. (so does German, just saying…)

Yes, English should always be one of the translations. :wink: (And Swedish)

As I suggested: Print language = English.

Edit:
Also, when David wondered about the extent I suggest that he go 100% multi lingual. Every little bit of strings that any user/party sees should be ML. Because it becomes part of the developement routine to do the strings and if all strings are handled the same way it simplifies instead of complicates the develoment cycle. This was one of the criterias I had for my ML system (it’s a nightmare if strings aren’t useful and can’t be synced during development).

Presentation of any data can then be printed or displayed on screen in any language.

// Rolf

1 Like

Ich würde nie Niederländisch als Sprache wählen, auch wenn es verfügbar wäre. Et bien sûr, que cela complique certaines activités; intercommunication, rapports d’erreurs, tutoriels… Faktom však je, že niektorí ľudia jednoducho nehovoria dostatočne anglicky, aby porozumeli anglickému používateľskému rozhraniu. Hoe ver denk je dat jij Grasshopper zou kunnen gebruiken als je alleen maar Finse tooltips voorgeschoteld krijgt?

Translations will have to be made, but because of the potential problems I really want to be able to switch languages on the fly, and perhaps even specify different target languages for different UI elements; English for component and tab names, Polish for tooltips and error messages.

1 Like

sounds reasonable. I don’t want to know what it says as well. Do you know that polish has 7 cases?

This would be the basic requirements. The command “Export Quick Image” should also have a selectable language for the captions on the components on the canvas. That’s the “document language” case which would apply to invoices and other documents in a regular business system.

// Rolf

1 Like

Rhino comes in Polish, so whatever the issues are we must have at least encountered them at some point. But like I said, apart from some vague goals I haven’t really given much thought to implementation yet.

1 Like

Even though my native language is Polish I can’t see myself as a user of “konika polnego”

1 Like

just making fun of it. Grasshopper is your baby, and if you believe its good to have then do it. It clearly isn’t a bad thing so why not. At least if the menu’s are localised, it may already be a great help for some people. I actually enjoy my German Rhino, although it annoys me to search for the english name of a command when writing in this forum, but its not that difficult. Besides that these problems could be solved in gh quite easily…

Furthermore, if you need a german localisation one day, just ask me.

Are you not trusting David’s Austrian German??

I’m fooling around trying to implement a simplified “LingualDomain” gh definition (extracted from the above diagram), but the first thing I experience is that the text panels doesn’t seem to support Unicode strings (this is in R6).

Edit: Ah, incorrect encoding in my csv-file, my bad. Changing to UTF8 fixed the encoding problem.

Edit: With correct encoding:

Hints about easiest way to “inject” strings to the components on the canvas are welcome (thinking of a central “string injector component” on the canvas which can replace strings (params & component names) according to current language settings (see slider upper left corner), for now only to make this test case a tad bit funnier to play with).

// Rolf

I also expect 「ja」

I wouldn’t, even after 5 years living here people still instantly peg me as a Dutchman.

bild

Ahum.

// Rolf