easy_localization

Creator: coderz1093

Last updated:

Add to Cart

Description:

easy localization

Easy and Fast internationalization for your Flutter Apps


















Why easy_localization? #

πŸš€ Easy translations for many languages
πŸ”Œ Load translations as JSON, CSV, Yaml, Xml using Easy Localization Loader
πŸ’Ύ React and persist to locale changes
⚑ Supports plural, gender, nesting, RTL locales and more
↩️ Fallback locale keys redirection
⁉️ Error widget for missing translations
❀️ Extension methods on Text and BuildContext
πŸ’» Code generation for localization files and keys.
πŸ›‘οΈ Null safety
πŸ–¨οΈ Customizable logger.

Getting Started #
πŸ”© Installation #
Add to your pubspec.yaml:
dependencies:
easy_localization: <last_version>
copied to clipboard
Create folder and add translation files like this
assets
└── translations
β”œβ”€β”€ {languageCode}.{ext} //only language code
└── {languageCode}-{countryCode}.{ext} //or full locale code
copied to clipboard
Example:
assets
└── translations
β”œβ”€β”€ en.json
└── en-US.json
copied to clipboard
Declare your assets localization directory in pubspec.yaml:
flutter:
assets:
- assets/translations/
copied to clipboard
πŸ”Œ Loading translations from other resources #
You can use JSON,CSV,HTTP,XML,Yaml files, etc.
See Easy Localization Loader for more info.
⚠️ Note on iOS #
For translation to work on iOS you need to add supported locales to
ios/Runner/Info.plist as described here.
Example:
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>nb</string>
</array>
copied to clipboard
βš™οΈ Configuration app #
Add EasyLocalization widget like in example
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:easy_localization/easy_localization.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();

runApp(
EasyLocalization(
supportedLocales: [Locale('en', 'US'), Locale('de', 'DE')],
path: 'assets/translations', // <-- change the path of the translation files
fallbackLocale: Locale('en', 'US'),
child: MyApp()
),
);
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: MyHomePage()
);
}
}
copied to clipboard
Full example
πŸ“œ Easy localization widget properties #



Properties
Required
Default
Description




key
false

Widget key.


child
true

Place for your main page widget.


supportedLocales
true

List of supported locales.


path
true

Path to your folder with localization files.


assetLoader
false
RootBundleAssetLoader()
Class loader for localization files. You can use custom loaders from Easy Localization Loader or create your own class.


extraAssetLoaders
false
null
A List of asset loaders, in case of needing assets being loaded from a different module or package. (e.g. adding a package that uses [Easy Localization Loader]).


fallbackLocale
false

Returns the locale when the locale is not in the list supportedLocales.


startLocale
false

Overrides device locale.


saveLocale
false
true
Save locale in device storage.


useFallbackTranslations
false
false
If a localization key is not found in the locale file, try to use the fallbackLocale file.


useFallbackTranslationsForEmptyResources
false
false
If translation is empty in the locale file, try to use the fallbackLocale file. Does not take effect if useFallbackTranslations is false.


useOnlyLangCode
false
false
Trigger for using only language code for reading localization files.Example:en.json //useOnlyLangCode: trueen-US.json //useOnlyLangCode: false


errorWidget
false
FutureErrorWidget()
Shows a custom error widget when an error occurs.



Usage #
πŸ”₯ Initialize library #
Call EasyLocalization.ensureInitialized() in your main before runApp.
void main() async{
// ...
// Needs to be called so that we can await for EasyLocalization.ensureInitialized();
WidgetsFlutterBinding.ensureInitialized();

await EasyLocalization.ensureInitialized();
// ...
runApp(....)
// ...
}
copied to clipboard
πŸ”₯ Change or get locale #
Easy localization uses extension methods [BuildContext] for access to locale.
It's the easiest way change locale or get parameters πŸ˜‰.
ℹ️ No breaking changes, you can use old the static method EasyLocalization.of(context)
Example:
context.setLocale(Locale('en', 'US'));

print(context.locale.toString());
copied to clipboard
πŸ”₯ Translate context.tr() #
Main function for translate your language keys
You can use extension methods of [String] or [Text] widget, you can also use tr() as a static function.
Text(context.tr('title'))
copied to clipboard
You can also use tr() without [Context] as a static function.
This is not recommend in build methods, because the widget won't rebuild when the language changes.
Text('title').tr() //Text widget

print('title'.tr()); //String

var title = tr('title') //Static function
copied to clipboard
Arguments:



Name
Type
Description




args
List<String>
List of localized strings. Replaces {} left to right


namedArgs
Map<String, String>
Map of localized strings. Replaces the name keys {key_name} according to its name


gender
String
Gender switcher. Changes the localized string based on gender string



Example:
{
"msg":"{} are written in the {} language",
"msg_named":"Easy localization is written in the {lang} language",
"msg_mixed":"{} are written in the {lang} language",
"gender":{
"male":"Hi man ;) {}",
"female":"Hello girl :) {}",
"other":"Hello {}"
}
}
copied to clipboard
// args
Text('msg').tr(args: ['Easy localization', 'Dart']),

// namedArgs
Text('msg_named').tr(namedArgs: {'lang': 'Dart'}),

// args and namedArgs
Text('msg_mixed').tr(args: ['Easy localization'], namedArgs: {'lang': 'Dart'}),

// gender
Text('gender').tr(gender: _gender ? "female" : "male"),

copied to clipboard
πŸ”₯ Plurals plural() #
You can translate with pluralization.
To insert a number in the translated string, use {}. Number formatting supported, for more information read NumberFormat class documentation.
You can use extension methods of [String] or [Text] widget, you can also use plural() as a static function.
Arguments:



Name
Type
Description




value
num
Number value for pluralization


args
List<String>
List of localized strings. Replaces {} left to right


namedArgs
Map<String, String>
Map of localized strings. Replaces the name keys {key_name} according to its name


name
String
Name of number value. Replaces {$name} to value


format
NumberFormat
Formats a numeric value using a NumberFormat class



Example:
{
"day": {
"zero":"{} Π΄Π½Π΅ΠΉ",
"one": "{} дСнь",
"two": "{} дня",
"few": "{} дня",
"many": "{} Π΄Π½Π΅ΠΉ",
"other": "{} Π΄Π½Π΅ΠΉ"
},
"money": {
"zero": "You not have money",
"one": "You have {} dollar",
"many": "You have {} dollars",
"other": "You have {} dollars"
},
"money_args": {
"zero": "{} has no money",
"one": "{} has {} dollar",
"many": "{} has {} dollars",
"other": "{} has {} dollars"
},
"money_named_args": {
"zero": "{name} has no money",
"one": "{name} has {money} dollar",
"many": "{name} has {money} dollars",
"other": "{name} has {money} dollars"
}
}
copied to clipboard
⚠️ Key "other" required!
//Text widget with format
Text('money').plural(1000000, format: NumberFormat.compact(locale: context.locale.toString())) // output: You have 1M dollars

//String
print('day'.plural(21)); // output: 21 дСнь

//Static function
var money = plural('money', 10.23) // output: You have 10.23 dollars

//Text widget with plural BuildContext extension
Text(context.plural('money', 10.23))

//Static function with arguments
var money = plural('money_args', 10.23, args: ['John', '10.23']) // output: John has 10.23 dollars

//Static function with named arguments
var money = plural('money_named_args', 10.23, namedArgs: {'name': 'Jane', 'money': '10.23'}) // output: Jane has 10.23 dollars
var money = plural('money_named_args', 10.23, namedArgs: {'name': 'Jane'}, name: 'money') // output: Jane has 10.23 dollars
copied to clipboard
πŸ”₯ Linked translations: #
If there's a translation key that will always have the same concrete text as another one you can just link to it. To link to another translation key, all you have to do is to prefix its contents with an @: sign followed by the full name of the translation key including the namespace you want to link to.
Example:
{
...
"example": {
"hello": "Hello",
"world": "World!",
"helloWorld": "@:example.hello @:example.world"
}
...
}
copied to clipboard
print('example.helloWorld'.tr()); //Output: Hello World!
copied to clipboard
You can also do nested anonymous and named arguments inside the linked messages.
Example:
{
...
"date": "{currentDate}.",
"dateLogging": "INFO: the date today is @:date"
...
}
copied to clipboard
print('dateLogging'.tr(namedArguments: {'currentDate': DateTime.now().toIso8601String()})); //Output: INFO: the date today is 2020-11-27T16:40:42.657.
copied to clipboard
Formatting linked translations:
Formatting linked locale messages
If the language distinguishes cases of character, you may need to control the case of the linked locale messages. Linked messages can be formatted with modifier @.modifier:key
The below modifiers are available currently.

upper: Uppercase all characters in the linked message.
lower: Lowercase all characters in the linked message.
capitalize: Capitalize the first character in the linked message.

Example:
{
...
"example": {
"fullName": "Full Name",
"emptyNameError": "Please fill in your @.lower:example.fullName"
}
...
}
copied to clipboard
Output:
print('example.emptyNameError'.tr()); //Output: Please fill in your full name
copied to clipboard
πŸ”₯ Reset locale resetLocale() #
Reset locale to device locale
Example:
RaisedButton(
onPressed: (){
context.resetLocale();
},
child: Text(LocaleKeys.reset_locale).tr(),
)
copied to clipboard
πŸ”₯ Get device locale deviceLocale #
Get device locale
Example:
print(context.deviceLocale.toString()) // OUTPUT: en_US
copied to clipboard
πŸ”₯ Delete save locale deleteSaveLocale() #
Clears a saved locale from device storage
Example:
RaisedButton(
onPressed: (){
context.deleteSaveLocale();
},
child: Text(LocaleKeys.reset_locale).tr(),
)
copied to clipboard
πŸ”₯ Get Easy localization widget properties #
At any time, you can take the main properties of the Easy localization widget using [BuildContext].
Are supported: supportedLocales, fallbackLocale, localizationDelegates.
Example:
print(context.supportedLocales); // output: [en_US, ar_DZ, de_DE, ru_RU]

print(context.fallbackLocale); // output: en_US
copied to clipboard
πŸ’» Code generation #
Code generation supports only json files, for more information run in terminal flutter pub run easy_localization:generate -h
Command line arguments #



Arguments
Short
Default
Description




--help
-h

Help info


--source-dir
-S
resources/langs
Folder containing localization files


--source-file
-s
First file
File to use for localization


--output-dir
-O
lib/generated
Output folder stores for the generated file


--output-file
-o
codegen_loader.g.dart
Output file name


--format
-f
json
Support json or keys formats


--[no-]skip-unnecessary-keys
-u
false
Ignores keys defining nested object except for pluarl(), gender() keywords.



πŸ”Œ Localization asset loader class #
Steps:

Open your terminal in the folder's path containing your project
Run in terminal flutter pub run easy_localization:generate
Change asset loader and past import.

import 'generated/codegen_loader.g.dart';
...
void main(){
runApp(EasyLocalization(
child: MyApp(),
supportedLocales: [Locale('en', 'US'), Locale('ar', 'DZ')],
path: 'resources/langs',
assetLoader: CodegenLoader()
));
}
...
copied to clipboard

All done!

πŸ“¦ Localization support for multi module/package project #
If you want to add localization support from other modules and packages you can add them via extraAssetLoaders parameter:
void main(){
runApp(EasyLocalization(
child: MyApp(),
supportedLocales: [Locale('en', 'US'), Locale('ar', 'DZ')],
path: 'resources/langs',
assetLoader: CodegenLoader()
extraAssetLoaders: [
TranslationsLoader(packageName: 'package_example_1'),
TranslationsLoader(packageName: 'package_example_2'),
],
));
}
copied to clipboard
πŸ”‘ Localization keys #
If you have many localization keys and are confused, key generation will help you. The code editor will automatically prompt keys
Steps:

Open your terminal in the folder's path containing your project
Run in terminal flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart
Past import.

import 'generated/locale_keys.g.dart';
copied to clipboard

All done!

How to use generated keys:
print(LocaleKeys.title.tr()); //String
//or
Text(LocaleKeys.title).tr(); //Widget
copied to clipboard
πŸ–¨οΈ Logger #
[Easy Localization] logger based on [Easy Logger]
You can customize logger for you project
Show only lost keys message #
Lost translations keys logged like warning messages. Change [Easy Logger] level for display only errors and warnings.
EasyLocalization.logger.enableLevels = [LevelMessages.error, LevelMessages.warning];
copied to clipboard
Logger off #
For disable logger, change Build Modes in [Easy Logger] to empty List;
EasyLocalization.logger.enableBuildModes = [];
copied to clipboard
Catching logger messages #
For catching logger messages you need override default printer function.
EasyLogPrinter customLogPrinter = (
Object object, {
String name,
StackTrace stackTrace,
LevelMessages level,
}) {
///Your function
print('$name: ${object.toString()}');
};

/// override printer to custom
EasyLocalization.logger.printer = customLogPrinter;
copied to clipboard
Read more about Easy Logger
βž• Extensions helpers #
String to locale #
'en_US'.toLocale(); // Locale('en', 'US')

//with custom separator
'en|US'.toLocale(separator: '|') // Locale('en', 'US')
copied to clipboard
Locale to String with separator #
Locale('en', 'US').toStringWithSeparator(separator: '|') // en|US
copied to clipboard





Screenshots #



Arabic RTL
English LTR
Error widget










Donations #
We need your support. Projects like this can not be successful without support from the community. If you find this project useful, and would like to support further development and ongoing maintenance, please consider donating.





Sponsors #

Contributors thanks #

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.