gen_l10n
| Package | Kind | Provides the role | Needs | Choose with |
|---|---|---|---|---|
smf_gen_l10n | infrastructure | Localization | preferences | -m gen_l10n |
gen_l10n keeps the texts of the app in ARB files, one for each language. gen-l10n, the generator of localizations in the Flutter SDK, turns them into the code that reads them. The app shows its texts in the language of the device, or in the one that the user chose, among the languages that the texts are in.
What it adds to the app
| File | What it holds |
|---|---|
l10n.yaml | The options of gen-l10n. |
lib/l10n/app_en.arb | Every text of the app in English. |
lib/l10n/app_<code>.arb | The translations into another language of the app, one file for each. |
lib/core/l10n/l10n.dart | context.l10n, the texts of the app in the language of a BuildContext. |
The module also adds generate: true to the flutter section of pubspec.yaml and the intl package to the dependencies, and gives the root MaterialApp the delegate of the texts, AppLocalizations.delegate.
With these, flutter pub get generates the AppLocalizations class in lib/l10n, in app_localizations.dart and a file for each language next to it. SMF does not write that code. smf create runs flutter pub get in the new app, so the app has the class when the run ends.
Whichever module provides it, the localization role adds lib/core/l10n/app_locale.dart with the languages of the app, appLocales, and the language that the user chose, appLocale, which the app remembers. The role also gives the root MaterialApp its locale, its supportedLocales and the delegates of Flutter's own texts, adds flutter_localizations to the dependencies, and names the languages of the app in ios/Runner/Info.plist. In an app with a settings screen, it adds the entry Language, in which the user chooses the language. Languages describes all of this, and Texts and languages how the texts of the modules get into the app.
The choice of the user is saved in the preferences, so an app with this module has a module that provides them. smf create adds shared_preferences by itself while it is the only one that does.
The README of the app gets a section "Texts" from the module and a section "Languages" from the role, with the steps of this page. In the guide for coding agents of the app, the role tells under "Localization" how code reads a text and where the languages are, and the module adds where the texts are, how to add one, and which files gen-l10n writes itself.
The texts
The modules and the roles of the app give their texts to the localization role, each in English and in the languages that its owner has it in. smf create writes them into the ARB files, each under the name of its getter. Every app has the two texts of the fallback start screen of flutter_core. In an app with this module alone, they are the whole file of Ukrainian:
{
"@@locale": "uk",
"flutterCoreFallbackHint": "Стартового екрана ще немає. Додайте фічу з маршрутом або замініть цей екран.",
"flutterCoreFallbackCopied": "Скопійовано"
}
The texts of the other modules of the app are in the file too, in the order of the modules. After the texts of the modules come those that the roles of the app add themselves, such as the texts of the entry of the language.
The file of another language has only the texts that are translated into it. A text that it lacks reads in English there.
Code reads a text through context.l10n, with lib/core/l10n/l10n.dart imported, where the context is one below the root of the app:
/// The texts of the app in the language of a context: `context.l10n`.
extension AppTexts on BuildContext {
/// The texts of the app in the language of this context, which is below
/// the root of the app.
///
/// gen-l10n of Flutter generates [AppLocalizations] from the ARB files in
/// `lib/l10n`: run `flutter gen-l10n` after every change of those files.
AppLocalizations get l10n => AppLocalizations.of(this);
}
Add a text
Add the text to lib/l10n/app_en.arb under a name of its own in lowerCamelCase, and its translations under the same name to the files of the other languages:
{
"@@locale": "en",
"cartTitle": "Your cart"
}
Then run flutter gen-l10n, which generates the getter, and read the text:
import 'package:my_app/core/l10n/l10n.dart';
Text(context.l10n.cartTitle)
Run flutter gen-l10n after every change of the ARB files. In a fresh clone of the app, flutter pub get generates the files that it writes, so you can commit lib/l10n/app_localizations*.dart or leave them out of the repository. Do not edit them.
Add a language
The texts of a new language go into a file of their own. For German:
- Add
lib/l10n/app_de.arbwith"@@locale": "de"and the translations. - Run
flutter gen-l10n.
The language then goes into the list of the languages of the app and two more places, which are the same with every module that provides the localization. Languages has those steps.
The options of gen-l10n
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
nullable-getter: false
use-escaping: false
nullable-getter: false makes AppLocalizations.of(context) return the texts and not a nullable value, so context.l10n needs no !. use-escaping: false turns the escapes of gen-l10n off, so write an apostrophe in a text once.
Choosing the languages
The app gets every language that a text of its modules and roles is in, with English first. --locales narrows and orders them, as in --locales en,uk. See Languages.
For module authors
A module gives its texts to the localization role and never to this module; see Texts. The class that gen-l10n generates has members of its own: localeName, of, delegate, localizationsDelegates and supportedLocales. smf create reports a text whose getter would have one of these names.
Choosing it
smf create asks which module provides the localization of the app, and offers None as well. Without such a module, the modules show their texts in English. To choose this one without the question:
smf create my_app -m gen_l10n
This app has no feature, so it starts on the fallback start screen of flutter_core, whose texts it shows in English or in Ukrainian, as the device prefers.