Dynamic translations in OutSystems Mobile apps

Using MultiLingual plugin — Save the translations in a text file instead of in the Local DB.

Teodomiro D. Santos
Noesis Low-Code Solutions
6 min readOct 24, 2019

--

In my 76 weeks journey as OutSystems developer — I am in a phase of my life where many of my former classmates and old friends are having babies, and very often when I ask them how old the kid is, they answer in week units, and then comes a weird moment of silence for my brain, which is highly trained on memorizing anime characters names and their powers, have to do the very unusual job of converting weeks in months/years without the help of a calculator; that’s why I’m using week units in everything in order to get my brain used to it — I found two main ways on handling translations in mobile apps in OutSystems:

  1. Using the MultiLingual plugin: have a Backoffice page where the translations are managed. And have in this same page a button to download a JSON file — with the data structure compatible with the MultiLingual plugin — containing the translations. The downloaded JSON file must be uploaded to the project of your mobile app, in Service Studio, as a resource, and then the action “AddTranlationsFromResource” is used to pass the translations to the plugin MultiLingual. The main downside of this approach is that every time you add/modify a translation in your Backoffice page you need to replace the JSON in your project and regenerate the binaries of the app — which may be bad if the client demands a dynamic way of managing the translations (= the edition of the translations is reflected immediately in the app without the intervention of the dev team). The main advantage of this approach is that the JSON file will be a Resource of application and it’s a simple text file, so the reading process of the translations is very fast - good performance.
  2. Using Local Storage and not the MultiLingual plugin: have a Backoffice page where the translations are managed. In the mobile app side, create a local entity for the translations. Such local entity is synchronized with the translation entity in the server side during the running of the client action OfflineDataSync. The main advantage of this approach is that one doesn’t have to regenerate the binaries of the application every time a translation was added/modified, for the translations are updated during the synchronization of the local data - allowing dynamic translation. The main downside of this approach is that the local database will be accessed for each text to be translated in the screen — bad performance.
  3. A third possibility is possible — got the genius word play “Possibility”, “possible”?… just like Eminem in the second verse of “In your head”, right? — although I’ve never seen it implemented, it’s possible to combine Local storage and the plugin Multilingual: The local entities can be synced at the stage of the “OfflineDataSync” running and then the list of translations from the local entity can be passed to the Multilingual plugin through the action AddTranslations. This approach basically solves the downsides of the first two approaches — no need to regenerate the binaries every time a translation is edited, and the local database won’t have to be accessed for every text to be translated in the screen, for the translation was passed to the plugin jurisdiction during the phase of synchronization of the local data, and as I said in the first approach the plugin has a good way of handling the translations (if you don’t believe, just ask me).
  4. I suggest a fourth approach. Using the plugin only, therefore, no local storage entities required just like in the first approach, but with the advantages of the third approach: The translations are edited at the Backoffice page and saved at the server entity just like in the previous approaches. But the server action that returns the translations to the mobile app returns a binary of a JSON file, containing the list of translations. In the side of the mobile app, during OnApplicationReady system event, this binary is retrieved and the JSON file is saved at the user’s device. Then the translations are loaded to the plugin MultiLingual through the action AddTranslations. Advantages of this approach: 1-No local storage needed (uses resource files instead); 2-Allows dynamic translation;

There’s this Paralympic athlete in Angola called Sayovo. Sayovo is blind and represented Angola in some Olympic games and won 3 gold medals for Angola so became a national star. Therefore, a lot of journalists interviewed him in that time. There’s a group of journalists who wanted to surprise him, so with the help of his wife they sneaked in his house and found him reading the newspaper. The journalists, astonished, asked him “Sayovo, wasn’t you born blind? How can you read?”. Sayovo, after some seconds of hard thinking wisely answered, “I’m not reading, I can understand the content of the newspaper just by the pictures”. The journalists sighed with relief and the interview proceeded. (Google “Sayovo Angola” if you don’t believe me). That’s why I do understand the value of pictures in publications, so I’m using a lot of them in order to increase the range of my target audience.

Dynamic translations in OutSystems mobile apps using the plugin MultiLingual

The approach I suggest (the fourth one) can be divided in 4 main steps as follow:

Step 1:

Backoffice page for add/edit the translations

Step 2, 3 and 4:

(Actually, just access the following link to access the code and take printscreens yourself: https://www.outsystems.com/forge/Component_Overview.aspx?ProjectId=6855 )

As Shakespeare once said:

(Of course the picture above isn’t fake, because, as everyone knows, there was no Photoshop during the time Shakespeare was alive. Photoshop came up thousands of weeks later.)

The server action mentioned in the Step 2 is the GetJSONTrans, can be found in the app “Todo Backoffice”, module Todo_Backoffice. The magics of the steps 3 and 4 are happening at the system event OnApplicationReady. I’m using the client action SaveFile from the plugin FilePlugin to save the JSON in the device and the action GetFileData to get the binary from it.

Conclusion

Currently the mobile devices are getting so powerful in terms of processing, that one can just ignore a lot of best practices while developing an app and still have a fast app. Hence the temptation to follow the idea “As long as it works, it’s fine” gets powerful as well. Needless to say for excellent programmers “get it working” isn’t good enough, they have to “get it working in the best possible way”. #JeSuisBestPractice.

And that’s all. If you know a better technique on how to use the Multilingual plugin, please, share with me. I love to learn best practices techniques. Thank you.

Ah, still about Sayovo, I heard that the international entity responsible for the Olympic games heard the same story I mentioned above so they asked Sayovo an urine sample in order to determine if he’s really a vision impaired person… he refused to give it and said, “Oh, I see… you guys don’t believe me”. Very suspicious, isn’t it?

Published By

Teodomiro dos Santos

--

--