4.5 KiB

Wyatt I18n

Style: Wyatt Analysis SDK: Flutter

This package aims to facilitate and improve the internationalization of your applications. It allows, among other things, to load translation files on the fly during the execution of the application.

Features

  • Load translation files

    • Load translation files from assets
    • Load translation files from the network
    • Load translation files from the file system
    • Load translation files from multiple sources
  • Supports multiple formats

    • Supports JSON format
    • Supports YAML format
    • Supports ARB formats
    • Supports CSV format
    • Supports custom formats parsers (see Parser class)
  • Usage

    • Detects the current locale
    • Act as a LocalizationDelegate
    • Act as a DataSource (in the sense of the Wyatt Architecture)
  • Other

    • Generate translation constants from fallback translation files

Usage

You can use this package as a LocalizationDelegate or as a DataSource.

As a LocalizationDelegate

It is recommended to use this package as a LocalizationDelegate. This allows you to use the context.i18n method to translate your strings. It follows the standard of the flutter_localizations package and you can use it in the MaterialApp widget as follows:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        I18nDelegate(
          dataSource: NetworkI18nDataSourceImpl(
            baseUri: 'https://i18n.wyatt-studio.fr/apps/flutter_demo',
          ),
          localeTransformer: (locale) => locale.languageCode,
        ),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      supportedLocales: [
        Locale('en'),
        Locale('fr'),
      ],
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

And in your widgets:

Text(context.i18n('youHavePushed', {'count': 42})),
// => 'You have pushed the button this many times: 42' in English
// => 'Vous avez appuyé sur le bouton ce nombre de fois: 42' in French

As a DataSource

This gives you more control over the internationalization of your application. You can handle the loading of the translation files yourself.

For example, if you want to create a Repository that will handle the loading of the translation files, you can do it.

Provide DataSource with GetIt:

// Initialize i18n
final I18nDataSource i18nDataSource =
    await AssetsI18nDataSourceImpl.withSystemLocale(
  basePath: 'l10n',
  baseName: 'intl',
  localeTransformer: (locale) => locale.languageCode,
);

// Initialize real sources/services
GetIt.I.registerLazySingleton<I18nDataSource>(
  () => i18nDataSource,
);

Create a Repository:

class I18nRepository {
  I18nRepository({
    required this.dataSource,
  });
  
  final I18nDataSource dataSource;

  Future<I18n> load() async {
    final i18n = await dataSource.load();
    return i18n;
  }
}

And use it in your cubit:

class MyCubit extends Cubit<MyState> {
  MyCubit({
    required this.i18nRepository,
  }) : super(MyState());

  final I18nRepository i18nRepository;

  Future<void> loadI18n() async {
    final i18n = await i18nRepository.load();
    emit(state.copyWith(i18n: i18n));
  }
}

Note: you should create a cache system to avoid reloading the translation files every time.