Flutter Getx Translation — Cyberneom

Serzen Montoya
4 min readSep 2, 2021

--

Hello everyone!

Following my thinking of sharing what I’m developing within Cyberneom, now I’m gonna talk about Translations and Internacionalization.

As part of the GetMaterialApp provided by Getx we have three properties called “translations”, “locale” and “fallbackLocale”. These properties are the ones needed in order to implement a translation module. This would be located at main.dart

Widget build(BuildContext context){
initializeDateFormatting('es_MX',"");
return GetMaterialApp(
navigatorKey: Catcher.navigatorKey,
translations: NeomTranslations(),
locale: Get.deviceLocale,
fallbackLocale: Locale('en', 'US'),

defaultTransition: Transition.upToDown,
debugShowCheckedModeBanner: false,
home: NeomRoot(),
initialRoute: NeomRouteConstants.ROOT,
getPages: NeomAppRoutes.routes,
);
}

In the code above we can see NeomTranslations(), also, Get.deviceLocale and Locale(‘en’, ‘US’).

class NeomTranslations extends Translations {
@override
Map<String, Map<String, String>> get keys => {}

NeomTranslation is extending the Translations class from Get which is part of the Internacionalization.dart file.

Once we start creating the NeomTranslations class, we have to add some keys, declaring our Locales.

For this case, I’m implementing the ‘en_US’ and ‘es_MX’ ones as I’m in Mexico and I wanted this app to have the English and Spanish version.

Map<String, Map<String, String>> get keys => {
'en_US': {},
'esp_MX': {}
}

Now, just to give an example of how to add words to translate I’m gonna show some titles and messages.

Map<String, Map<String, String>> get keys => {
'en_US': {
'slogan': 'Guide a meditation with your own voice',
'googleLogin': 'Login with Google',
'facebookLogin': 'Login with Facebook',
'emailLogin': 'Login with Email',
'home': 'Home',
'add': 'Add',
'events': 'Events',
'featureAvailableSoon': 'This feature would be available soon',
'introLocale': 'Choose the language of your preference',
'introProfileType': 'Choose a mode to start',
'introProfileSelection': 'Profile Selection',
'introFrequency': 'Frequency Selection',
},
'esp_MX': {
'slogan': 'Meditación guiada con tu propia voz',
'googleLogin': 'Iniciar con Google',
'facebookLogin': 'Iniciar con Facebook',
'emailLogin': 'Iniciar con Email',
'home': 'Inicio',
'add': 'Agregar',
'events': 'Eventos',
'featureAvailableSoon': 'Esta funcionalidad estará disponible pronto',
'introLocale': 'Elige el lenguaje de tu preferencia',
'introProfileType': 'Elige una opción para comenzar',
'introProfileSelection': 'Selección de Perfil',
'introFrequency': 'Selección de Frequencias',
}
}

What I would suggest is to start annoting every message and title and indication as soon as we recognize it. If if start accumulating words we could block ourselves and this would be an extra effort in the future.

Also, in order to have a better structure I created two more classes as Constants. Using this type of constants we could save a lot of refactoring time.

class NeomTranslationConstants {
static const String slogan = 'slogan';
static const String introLocale = "introLocale";
static const String introProfileType = "introProfileType";
static const String frequencySelection = "frequencySelection";
static const String introFrequency = "introFrequency";
static const String introFrequencyMsg = "introFrequencyMsg";
static const String introNeomReason = "introNeomReason";
}

The same goes for MessageTranslationConstants. Using this we can start thinking in custom messages with internacionalization as ‘errorLoginGoogle’

class MessageTranslationConstants {
static const String errorLoginGoogle = 'errorLoginGoogle';
static const String errorLoginFacebook = 'errorLoginFacebook';
static const String errorLoginSpotify = 'errorLoginSpotify';
static const String errorLoginEmail = 'errorLoginEmail';
static const String forgotPassword = 'forgotPassword';
static const String passwordReset = 'passwordReset';
static const String errorHandlingAuth = 'errorHandlingAuth';
static const String errorSigningOut = 'errorSigninOut';
static const String errorCreatingAccount = 'errorCreatingAccount';
}

We could find the constants above in our NeomTranslation class as:

Map<String, Map<String, String>> get keys => {
'en_US': {
'errorLoginGoogle': "Error login-in with Google account",
},
'esp_MX': {
'errorLoginGoogle': "Error iniciando sesión con Facebook",
}
}

Now, in order to use it in realtime as running the app, we have to implement the “.tr” (from Trans) which is within the “import ‘package:get/get.dart’” import. We can find an example in the HeaderIntro widget shown below.

return GetBuilder<OnBoardingController>(
id: NeomPageIdConstants.onBoardingNeomReason,
init: OnBoardingController(),
builder: (_) => Scaffold(
body: Container(
child: Center(
child: Column(
children: <Widget>[
HeaderIntro(
subtitle: NeomTranslationConstants.introNeomReason.tr),
SizedBox(height: 50),
],
),
),
),
),
);

Thanks for your attention, if you want to know more about this way of using Getx, you can check the Cyberneom repository. Also I’m open to collaboration for this project and another app concept I’m developing (or thinking about lol).

--

--

Serzen Montoya
Serzen Montoya

Written by Serzen Montoya

Musician, writer, developer and founder of: EscritoresMXI, Gigmeout and Cyberneom. Meditation | Cybernetics | Poetry | Spirituality | Philosophy

No responses yet