i18n

Last updated:

0 purchases

i18n Image
i18n Images
Add to Cart

Description:

i18n

i18n #

Simple internationalization package for Dart and Flutter. This package is a permanent fork of another
internationalization package [https://github.com/fnx-io/i69n]. This package now supports hot reload and is tested on
latest versions of Flutter.
Overview #
Write your messages into YAML files, and let this package generate convenient Dart classes from those files.
Turn this YAML file:
lib/messages.i18n.yaml

button:
save: Save
load: Load
users:
welcome(String name): "Hello $name!"
logout: Logout
copied to clipboard
Into these generated Dart classes:
class Messages {
const Messages();
ButtonMessages get button => ButtonExampleMessages(this);
UsersMessages get users => UsersExampleMessages(this);
}
class ButtonMessages {
final Messages _parent;
const ButtonMessages(this._parent);
String get save => "Save";
String get load => "Load";
}
class UsersMessages {
final Messages _parent;
const UsersMessages(this._parent);
String get logout => "Logout";
String welcome(String name) => "Hello $name!";
}
copied to clipboard
... and use them in your code - plain and simple.
Messages m = Messages();
print(m.users.welcome('World'));
// outputs: Hello World!
copied to clipboard
Package is an extension (custom builder) for build_runner
(Dart standard for source generation) and it can be used with Flutter, AngularDart
or any other type of Dart project.
Motivation and goals #

The official Dart/Flutter approach to i18n seems to be ... complicated and kind of ... heavyweight.
I would like my messages to be checked during compile time. Is that message really there?
Key to the localized message shouldn't be just some arbitrary String, it should be a getter method!
And if the message takes some parameters, the method should take those parameters!
I like to bundle messages into thematic groups, the i18n tool should support that and help me with it.
Dart has awesome string interpolation, I want to leverage that!
I like build_runner and code generation.

Solution #
Write your messages into a YAML file:
messages.i18n.yaml (default messages):

generic:
ok: OK
done: DONE
invoice:
create: Create invoice
delete: Delete invoice
copied to clipboard
Write your translations into other YAML files:
messages_de.i18n.yaml (_de = German translation)

generic:
ok: OK
done: ERLEDIGT
invoice:
create: Rechnung erstellen
delete: Rechnung löschen
copied to clipboard
... run the webdev tool, or build_runner directly, and use your messages like this:
Messages m = Messages();
print(m.generic.ok); // output: OK
print(m.generic.done); // output: DONE

m = Messages_de();
print(m.generic.ok); // output: OK
print(m.generic.done); // output: ERLEDIGT
copied to clipboard
Parameters and pluralization #
The implementation is VERY straightforward, which allows you to do all sorts of crazy stuff:
invoice:
create: Create invoice
delete: Delete invoice
help: "Use this function
to generate new invoices and stuff.
Awesome!"
count(int cnt): "You have created $cnt ${_plural(cnt, one:'invoice', many:'invoices')}."
apples:
_apples(int cnt): "${_plural(cnt, one:'apple', many:'apples')}"
count(int cnt): "You have eaten $cnt ${_apples(cnt)}."
copied to clipboard
Now see the generated classes:
class Messages {
const Messages();
InvoiceMessages get invoice => InvoiceExampleMessages(this);
ApplesMessages get apples => ApplesExampleMessages(this);
}

class InvoiceMessages {
final Messages _parent;
const InvoiceMessages(this._parent);
String get create => "Create invoice";
String get help => "Use this function to generate new invoices and stuff. Awesome!";
String get delete => "Delete invoice";
String count(int cnt) => "You have created $cnt ${_plural(cnt, one:'invoice', many:'invoices')}.";
}

class ApplesMessages {
final Messages _parent;
const ApplesMessages(this._parent);
String _apples(int cnt) => "${_plural(cnt, one:'apple', many:'apples')}";
String count(int cnt) => "You have eaten $cnt ${_apples(cnt)}.";
}
copied to clipboard
See how you can reuse the pluralization of _apples(int cnt)? (nice!)
There are three functions you can use in your message:
String _plural(int count, {String zero, String one, String two, String few, String many, String other})

String _cardinal(int count, {String zero, String one, String two, String few, String many, String other})

String _ordinal(int count, {String zero, String one, String two, String few, String many, String other})
copied to clipboard
_plural and _cardinal do the same. I just felt that _plural
is a little bit less scary name :-)
We need only two forms of the word "apple" in English. "Apple" (one) and "apples" (many).
But in some languages like Czech, we need three:
apples:
_apples(int cnt): "${_plural(cnt, one:'jablko', few: 'jablka', many:'jablek')}"
copied to clipboard
See also:

http://cldr.unicode.org/index/cldr-spec/plural-rules
https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html

How to use generated classes #
How to decide what translation to use (ExampleMessages_de?, ExampleMessages_hu?) is up to you.
The package simply generates message classes, that's all.
import 'messages.i18n.dart';
import 'messages_de.i18n.dart' as de;

void main() async {
Messages m = Messages();
print(m.apples.count(1));
print(m.apples.count(2));
print(m.apples.count(5));

m = de.Messages_de(); // see? ExampleMessages_cs extends ExampleMessages
print(m.apples.count(1));
print(m.apples.count(2));
print(m.apples.count(5));
}
copied to clipboard
Where and how to store instances of these message classes -
again, up to you. I would consider ScopedModel for Flutter and registering
messages instance into dependency injection in AngularDart.
But in this case a singleton would be acceptable also.
How to use with Flutter #
Create YAML file with your messages, for example:
lib/messages/foo.i18n.yaml
copied to clipboard
Add build_runner as a dev_dependency and i18n as a dependency to pubspec.yaml:
dependencies:
flutter:
sdk: flutter
i18n: any
...

dev_dependencies:
build_runner: any
flutter_test:
sdk: flutter
copied to clipboard
Open a terminal and in the root of your Flutter project run:
flutter packages pub run build_runner watch
copied to clipboard
... and keep it running. Your message classes will appear next to YAML files and will be
rebuilt automatically each time you change the source YAML.
For one-time (re)build of your messages run:
flutter packages pub run build_runner build
copied to clipboard
Import generated messages and use them:
import 'packages:my_app/messages/foo.i18n.dart'

...

Foo m = Foo();
return Text(m.bar);
...
copied to clipboard
How to use with AngularDart #
You are probably using webdev tool already, so you just need to add i18n
as a dependency and that's all.
Custom pluralization #
The package can correctly decide between 'one', 'few', 'many', etc. only for
English and Czech (for now). But you can easily plug your own language,
see example/main.dart
and Czech and English
implementation.
If you implement support for your language, please let me know,
I'll gladly embed it into the package.

License:

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

Customer Reviews

There are no reviews.