fast_i18n
lightweight i18n solution. use json files to create typesafe translations.
getting started
step 1: add dependencies
dependencies:
fast_i18n: ^3.0.2
dev_dependencies:
build_runner: any
step 2: create json files
create these files inside your lib
directory. preferably in one common package like lib/i18n
.
only files having the .i18n.json
file extension will be detected. you can configure it.
strings.i18n.json (default, fallback)
{
"hello": "hello $name",
"save": "save",
"login": {
"success": "logged in successfully",
"fail": "logged in failed"
}
}
strings_de.i18n.json
{
"hello": "hallo $name",
"save": "speichern",
"login": {
"success": "login erfolgreich",
"fail": "login fehlgeschlagen"
}
}
step 3: generate the dart code
flutter pub run build_runner build
step 4: initialize
a) use device locale
void main() {
widgetsflutterbinding.ensureinitialized(); // add this
localesettings.usedevicelocale(); // and this
runapp(myapp());
}
b) use specific locale
@override
void initstate() {
super.initstate();
string storedlocale = loadfromstorage(); // your logic here
localesettings.setlocale(storedlocale);
}
step 4a: override ‘supportedlocales’
this is optional but recommended.
standard flutter controls (e.g. back button’s tooltip) will also pick the right locale.
materialapp(
localizationsdelegates: const [
globalmateriallocalizations.delegate,
globalwidgetslocalizations.delegate,
globalcupertinolocalizations.delegate,
],
supportedlocales: localesettings.supportedlocales, // <---
)
step 4b: ios configuration
file: ios/runner/info.plist
<key>cfbundlelocalizations</key>
<array>
<string>en</string>
<string>de</string>
</array>
step 5: use your translations
text(t.login.success); // plain
text(t.hello(name: 'tom')); // with argument
text(t.step[3]); // with index (for arrays)
text(t.type['warning']); // with key (for maps)
// advanced
translationprovider(child: myapp()); // wrap your app with translationprovider
// [...]
final t = translations.of(context); // forces a rebuild on locale change
string translateadvanced = t.hello(name: 'tom');
api
when the dart code has been generated, you will see some useful classes and functions
t
– the translate variable for simple translations
translations.of(context)
– translations which reacts to locale changes
translationprovider
– app wrapper, used for translations.of(context)
localesettings.usedevicelocale()
– use the locale of the device
localesettings.setlocale('de')
– change the locale
localesettings.setlocaletyped(applocale.en)
– change the locale (typed version)
localesettings.currentlocale
– get the current locale
localesettings.currentlocaletyped
– get the current locale (typed version)
localesettings.locales
– get the supported locales
localesettings.supportedlocales
– see step 4a
configuration
all settings can be set in the build.yaml
file. place it in the root directory.
targets:
$default:
builders:
fast_i18n:i18nbuilder:
options:
base_locale: en
input_directory: lib/i18n
input_file_pattern: .i18n.json
output_directory: lib/i18n
output_file_pattern: .g.dart
translate_var: t
enum_name: applocale
key_case: snake
maps:
- a
- b
- c.d
key | type | usage | default |
---|---|---|---|
base_locale | string |
locale of default json | en |
input_directory | string |
path to input directory | null |
input_file_pattern | string |
input file pattern | .i18n.json |
output_directory | string |
path to output directory | null |
output_file_pattern | string |
output file pattern | .g.dart |
translate_var | string |
translate variable name | t |
enum_name | string |
enum name | applocale |
key_case | camel , pascal , snake |
transform keys (optional) | null |
maps | list<string> |
entries which should be accessed via keys | [] |
faq
how do i add arguments?
use the $
prefix.
in edge cases you can also wrap it with ${...}
.
{
"greeting": "hello $name",
"distance": "${distance}m"
}
t.greeting(name: 'tom'); // hello tom
t.distance(distance: 4.5); // 4.5m
how can i access translations using maps?
define the maps in your build.yaml
.
keep in mind that all nice features like autocompletion are gone.
strings.i18n.json
{
"welcome": "welcome",
"thisisamap": {
"hello world": "hello"
},
"classicclass": {
"hello": "hello",
"amapinclass": {
"hi": "hi"
}
}
}
build.yaml
targets:
$default:
builders:
fast_i18n:i18nbuilder:
options:
maps:
- thisisamap
- classicclass.amapinclass
now you can access the translations via keys:
string a = t.thisisamap['hello world'];
string b = t.classicclass.hello; // the "classical" way
string c = t.classicclass.amapinclass['hi']; // nested
can i use lists?
lists are fully supported. you can also put lists or maps inside lists!
{
"nicelist": [
"hello",
"nice",
[
"first item in nested list",
"second item in nested list"
],
{
"wow": "wow!",
"ok": "ok!"
},
{
"a map entry": "access via key",
"another entry": "access via second key"
}
]
}
string a = t.nicelist[1]; // "nice"
string b = t.nicelist[2][0]; // "first item in nested list"
string c = t.nicelist[3].ok; // "ok!"
string d = t.nicelist[4]['a map entry']; // "access via key"
Comments are closed.