A Better Flutter App #4
Supply localization and Internationalization in a better way.
One of a series of articles detailing a comprehensive starter app. This app is generated by a template offered by the package, app_template, which uses the underlying framework, mvc_application, based on the MVC design pattern.
I Like Screenshots. Tap Caption For Gists.
As always, I prefer using screenshots in my articles over gists to show concepts rather than just show code. I find them easier to work with frankly. However, you can click or tap on their captions to see the code in a gist or in Github. Tap or click on the screenshots themselves to zoom in on them for a closer look.
No Moving Pictures, No Social Media
There will be gif files in this article demonstrating aspects of the topic at hand. However, it’s said viewing such gif files is not possible when reading this article on platforms like Instagram, Facebook, etc. They may come out as static pictures or simply blank placeholder boxes. Please, be aware of this and maybe read this article on medium.com
Now, this is no reflection on Johannes Milke and his work. He, in fact, is a prolific YouTuber producing excellent content on the subject of Flutter, and I highly recommend his channel, Johannes Milke. However, when viewing the tutorial video, Create Multi-Language App (i18n)  Internationalization In Flutter, you really get a sense of how convoluted and arduous it is to set up and maintain a multi-language capability in your Flutter app — particularly when adding your own localized messages into those many .arb files.
Happily, two years ago I came upon Thomas Ecalle’s FlappyTranslator Dart package which inspired me to write my own Dart package called, i10n_translator. I even wrote a free article about it called, Do You Speak A-My Language?!
The one aspect I liked about it was not needing the many .arb files as described in the documentation, Internationalizing Flutter apps, and instead utilizing what I feel is a simpler approach involving a comma-separated values file (.csv) thus allowing for those ‘no-so-technical’ individuals to input and update the app’s translations. ‘Keep it simple’ has always been my motto. Besides, filling in translations is something we programmers don’t like to do anyway. That, and documentation — but I digress! Below is a screenshot of such a CSV file. There, you see the English words assigned to an app followed by their French and then Spanish translations.
Now, of course, the starter app has its own multi-language capability with its own i10n.csv file (see below). And, as you may have guessed, that means the underlying framework indeed uses the i10n_translator package. In this article, we’ll look to the starter app as an example as to how you would implement an alternative approach to multi-lingual capability for your app.
The first line in that .csv file lists out the languages currently supported separated by commas. Each subsequent line lists those translations in the order specified. If you like, you can have those lines perforated with blank lines for readability. Finally, it’s the first column in this .csv file that contains the key values used to look up the appropriate translations. There. Done. Get on with your life.
Back at the starter app’s ‘State object’, just place the static property, I10n.supportedLocales, into the ‘supportedLocales’ parameter. The i10n_translator package will then find those language codes listed in the .csv file, and you’re good to go. Of course, include the ‘I10n’ delegate along with the other usual delegates, and you’re all done. Of course, you still have to supply the translations directly to the app’s screens. Again, the i10n_translator package comes to the rescue.
Looking at the starter app’s popup menu options, you’ll see the static functions, s() and t(), coming from the 10n_translator package are being called with every option listed in the menu. ‘s’, refers to the String class, and ‘t’ refers to the TextWidget. The first function will return a translation (if any) in the form of a String object, while the second, in the form of a TextWidget. Easy peasy.
Note, the first column (the ‘key column’) of those words listed in the I10n.csv file correspond to the arguments passed into these two functions above. If no corresponding translation is found, the key value is merely displayed instead. As you can see in the gif files below, it makes for a seemingly effortless transition of the translations. What do you think?
Yet another crucial functionality every Flutter app worth its weight should have. With this article being number five in this series, that’s now five very important and even essential features supplied by the underlying framework package, mvc_application. Eight more or so to go, and we’ll have it!