marcglasberg / i18n_extension Goto Github PK
View Code? Open in Web Editor NEWFlutter package: Easy and powerful internationalization using Dart extensions.
License: Other
Flutter package: Easy and powerful internationalization using Dart extensions.
License: Other
Enhancement Request:
New parameter for I18n bool useLanguageCodeOnly = false
Description: whatever locale is set by initialLocale
or I18n.of(context).locale
it should only use the language code from the given locale. This allows to reduce translations files like this:
extension Localization on String {
String get i18n => localize(this, _t);
static final _t = Translations('en') +
{
'en': 'Current i18n locale is',
'de': 'Aktuelle i18n Sprache ist',
} + ...
Hi, I started to use your plugin this week, so I'm still at discovery stage.
One of features I try to implement is having translations by language not key. And today after your update I tried to follow docs, specifically this one:
static var _t = Translations.byLocale("en", "US") +
{
"en_us": {
"Hi.": "Hi.",
"Goodbye.": "Goodbye.",
},
"es_es": {
"Hi.": "Hola.",
"Goodbye.": "Adiós.",
}
};
But in the plugin itself (1.3.0) I cannot create Locale by two Strings, it still require one combined String. It may be desired behaviour but still it's inconsistency between docs and actual code.
I'm a little bit confused. I'm trying to add some tests, just to get in touch with it but for some reason it doesn't work as I expected. Actually, I'm trying to understand this example:
Translations.missingKeys.clear();
Translations.missingTranslations.clear();
// This should call recordKey().
"Hello World".i18n;
expect(Translations.missingKeys.length, 1);
expect(Translations.missingKeys.single.locale, "");
expect(Translations.missingKeys.single.text, "Marked habit");
expect(Translations.missingTranslations, isEmpty);
When I'm running the test file, I get the output ➜ Translation key in '' is missing: "Hello World".
. Why the output doesn't show the locale?
This may be irrelevant but It will be great if we can have list of languages with codes from system.
Hello,
Thanks for the great library. Does it support app/launcher name localization? If not, is it possible to add this new feature?
Hello,
I just want add i18n support to my app.I just find your awesome extension.I followed tutorial but its not worked(Its not change lang) so i just searched for my mistakes.Followed official flutter i18n tutorial and checked this extension issues.I found my problem.I need add these to MaterialApp
https://flutter.dev/docs/development/accessibility-and-localization/internationalization
MaterialApp(
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', "US"), // En
const Locale('tr', "TR"), // TR
],
...
),
home: I18n(child: screen()))
So its my first time on i18n and i dont know to do this.If you add this to readme file i think its will be helpfull for others
Good day Sir, i have an issue or maybe i just dont get something. This is my widgets tree
class MyMainApp extends StatelessWidget {
const MyMainApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder<SharedPreferences>(
future: SharedPreferences.getInstance(),
builder:
(BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
if (!snapshot.hasData) {
return _MySplashScreen();
}
return ChangeNotifierProvider<MyAppSettings>.value(
value: MyAppSettings(snapshot.data),
child: _MyMainApp(),
);},);}}
Here i try to call I18n with routes table
class _MyMainApp extends StatelessWidget {
const _MyMainApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return **I18n** (child: MaterialApp(
title: 'DS',
theme: Provider.of<MyAppSettings>(context).isDarkMode
? DarkTheme
: LightTheme,
routes: AppRoutingTable,
)); }
}
this is my route table map
final Map<String, WidgetBuilder> AppRoutingTable = {
Navigator.defaultRouteName: (context) => HomeRoute,
for (MyRoute route in AllRoutes) route.routeName: (context) => route,
};
const HomeRoute =
MyRoute ( child:
MyHomePage(),
title: "DEMO2",
routeName: Navigator.defaultRouteName,
);
MyHomePage contain Scaffold with
floatingActionButton: FloatingActionButton(onPressed: () =>
I18n.of(context).locale = (I18n.localeStr == "pt_br") ? null : Locale("pt_BR")),
and
bottomNavigationBar: BottomNavigationBar(
items:
<BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: Colors.blue,
title: Text(
"Hello.i18n",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20),
))
and with this i've create home_page.i18n.dart with
extension Localization on String {
//
static var t = Translations("en_us") +
{
"en_us": "Hello",
"pt_br": "Demonstração i18n",
};
String get i18n => localize(this, t);
String fill(List<Object> params) => localizeFill(this, params);
String plural(int value) => localizePlural(value, this, t);
String version(Object modifier) => localizeVersion(modifier, this, t);
Map<String, String> allVersions() => localizeAllVersions(this, t);
}
so i got and error NoSuchMethodError: The method "replaceAll' was called on null.
The locale en_
does not get mapped onto en
locale.
So when the local is en_
, then with the translations from below it will throw the error:
➜ There are no translations in 'en_' for "not_found".
import 'package:i18n_extension/i18n_extension.dart';
extension Localization on String {
static var t = Translations.byLocale("de") +
{
"en": {
"not_found": "404 not found",
},
"de": {
"not_found": "404 nicht gefunden",
},
};
String get i18n => localize(this, t);
}
i want to translate interploated String,
for example:
"Harry like %s"
I am using flutter pub run i18n_extension:getstrings
to extract my string.
How to a extract from an array.
Each translation file like flutter_input/lib/src/country.i18n.dart
from https://github.com/djarjo/flutter_input
extension Localization on String {
String get i18n => localize(this, _t);
static final _t = Translations('en') +
{
'en': 'Australia',
'de': 'Australien',
} +
produces a pub.dev issue when uploading a package:
Local variable _t not used.
I modified the file to have _t
as a class local variable but that seems a bit strange.
Hi,
I need this to work with flutter localization.
I have a custom AppLocalizations, when ever there is locale changed, I want to propagate the changes to i18n too, without the context.
Btw, could you provide a example or sample code how to have this work with flutter localization.
Thanks in advance.
Please write country codes in your examples as 2 uppercase letters according to IANA. See
https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
Scroll down to see the region codes.
I copyed the example code:
`import 'package:i18n_extension/i18n_extension.dart';
extension Localization on String {
static var _t = Translations("en_us") +
{
"en_us": "Hello, how are you?",
"pt_br": "Olá, como vai você?",
"es": "¿Hola! Cómo estás?",
"fr": "Salut, comment ca va?",
"de": "Hallo, wie geht es dir?",
};
String get i18n => localize(this, _t);
}`
but I get this error:
how can i fix this bug?
As this package depends on sprintf
and the version is lower than 4.1.0
, it cannot be used with new Dart features (without dependency overrides).
This is a mirror of the issue in sprintf
.
When I ran my Flutter app on the Web I ran across this issue:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
js_primitives.dart:30 The following UnsupportedError was thrown building _InheritedI18n:
Unsupported operation: Platform._operatingSystem
The relevant error-causing widget was:
_InheritedI18n
file:///home/dennis/.pub-cache/hosted/pub.dartlang.org/i18n_extension-1.4.0/lib/i18n_widget.dart:154:12
This is strange because it has nothing to do with native functionality and, besides, it is listed as supported on pub.dev
yuecelm@laptop:~/git/i18n_extension$ git rev-parse HEAD
08e4a78b00b165a26fb834640c48a615f3c56556
yuecelm@laptop:~/git/i18n_extension$ flutter test
Running "flutter pub get" in i18n_extension... 1.3s
00:07 +10: /home/yuecelm/git/i18n_extension/test/i18n_extension_test.dart: Translate manually.
➜ Translation key in 'en_us' is missing: "Goodbye".
00:07 +11: /home/yuecelm/git/i18n_extension/test/default_import_test.dart: Record missing keys used with .i18n of the default import.
➜ Translation key in '' is missing: "Hello".
00:07 +11: /home/yuecelm/git/i18n_extension/test/i18n_extension_test.dart: Translate using the extension.
➜ Translation key in 'en_us' is missing: "XYZ".
➜ Translation key in 'en_us' is missing: "XYZ".
00:07 +12: /home/yuecelm/git/i18n_extension/test/default_import_test.dart: Record missing keys used with .i18n of the default import.
➜ Translation key in '' is missing: "Goodbye".
00:07 +12: /home/yuecelm/git/i18n_extension/test/i18n_extension_test.dart: Record missing keys and missing translations.
➜ Translation key in 'en_us' is missing: "Unknown text".
➜ There are no translations in 'xx_yy' for "Hi.".
00:07 +14: /home/yuecelm/git/i18n_extension/test/default_import_test.dart: Record missing keys used with .plural() of the default import.
➜ Translation key in '' is missing: "There are %d people".
00:07 +16: /home/yuecelm/git/i18n_extension/test/i18n_extension_test.dart: Translations with version.
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
➜ Translation key in 'en_us' is missing: "�MyKey�0�abc�1�def�2�ghi�M�jkl�5�mno".
00:08 +24 -1: /home/yuecelm/git/i18n_extension/test/key_and_value_test.dart: The translatable key is usually the same as the default locale translation, but it can be different.For example { '': 'Good evening' } means that 'Good evening' is the key, and you can provide an English translation which is different than that, even if English is the default locale. This is to support the use case when you want to have fixed keys, which is NOT the preferred way to do it, but may be necessary for some advanced use cases. [E]
No default translation for 'en_us'.
package:i18n_extension/i18n_extension.dart 345:7 Translations.+
key_and_value_test.dart 93:9 Localization.t
key_and_value_test.dart 79:14 Localization.t
key_and_value_test.dart 99:37 Localization.i18n
key_and_value_test.dart 49:20 main.<fn>
00:08 +24 -2: /home/yuecelm/git/i18n_extension/test/key_and_value_test.dart: Should not accept empty keys or values. [E]
No default translation for 'en_us'.
package:i18n_extension/i18n_extension.dart 345:7 Translations.+
key_and_value_test.dart 68:35 main.<fn>
00:08 +24 -2: /home/yuecelm/git/i18n_extension/test/fallback_test.dart: If the translation to the exact locale is found, this will be returned. Otherwise, it tries to return a translation for the general language of the locale. Otherwise, it tries to return a translation for any locale with that language. Otherwise, it tries to return the key itself (which is the translation for the default locale).
➜ There are no translations in 'en_uk' for "Mobile phone".
➜ There are no translations in 'en' for "Mobile phone".
➜ There are no translations in 'pt_mo' for "Mobile phone".
➜ There are no translations in 'pt' for "Mobile phone".
➜ There are no translations in 'xx' for "Mobile phone".
➜ There are no translations in 'xx_yy' for "Mobile phone".
➜ There are no translations in 'pt_pt' for "Address".
➜ There are no translations in 'xx' for "Address".
➜ There are no translations in 'xx_yy' for "Address".
00:08 +25 -2: /home/yuecelm/git/i18n_extension/test/fallback_test.dart: If the translation to the exact locale is found, this will be returned. Otherwise, it tries to return a translation for the general language of the locale. Otherwise, it tries to return a translation for any locale with that language. Otherwise, it tries to return the key itself (which is the translation for the default locale).
➜ There are no translations in 'en_us' for "Mobile phone".
➜ There are no translations in 'en__us' for "Mobile phone".
➜ There are no translations in 'pt_mo' for "Mobile phone".
➜ There are no translations in 'pt' for "Mobile phone".
➜ There are no translations in 'xx' for "Mobile phone".
➜ There are no translations in 'xx_yy' for "Mobile phone".
➜ There are no translations in 'pt__br' for "Mobile phone".
➜ There are no translations in 'pt_pt' for "Address".
➜ There are no translations in 'xx' for "Address".
➜ There are no translations in 'xx_yy' for "Address".
00:08 +27 -2: Some tests failed.
Enhancement Request:
New method setLocale( Locale newLocaleToUse )
which uses the given locale for all further translations but without invoking setState()
from within I18n.
Reason: there is NO solution to properly integrate with MaterialApp (see #10 ). I added additional reasons under that issue.
Hello Marcelo,
First of all, thank you for making i18n_extension plugin - it has helped me a lot in my latest project and I will surely use it again in my next Flutter project - it is so easy to set up and use and the code boilerplate is indeed very minimal.
Let me suggest a simple addition to your code (although I have a Github account, I have never used a pull request to contribute to code and I do not want to break things).
For plurals you use:
/// Plural modifier for zero elements.
String zero(String text) => modifier("0", text);
/// Plural modifier for 1 element.
String one(String text) => modifier("1", text);
/// Plural modifier for 2 elements.
String two(String text) => modifier("2", text);
However, in Czech (my language) we use special word form also for amounts 3 and 4 (I am not sure if this applies to other languages as well). For amounts 5 and higher the form stays the same. Simply adding these two modifiers fixed this for me:
/// Plural modifier for 3 elements.
String three(String text) => modifier("3", text);
/// Plural modifier for 4 elements.
String four(String text) => modifier("4", text);
Example:
1 beer 1 pivo
2 beers 2 piva
3 beers 3 piva
4 beers 4 piva
5 beers 5 piv
6 beers 6 piv
7 ... 7 ...
The 'times' modifier can stay as is as most people would not care about 3 and 4 times as we Czechs do.
/// Plural modifier for any number of elements, except 0, 1 and 2.
String times(int numberOfTimes, String text) {
assert(numberOfTimes != null && (numberOfTimes < 0 || numberOfTimes > 2));
return modifier(numberOfTimes, text);
}
Tomáš Jeřábek
Consultant/Developer
Having worked with gettext before, the approach used in your project is very familiar in that source strings are used as identifiers.
xgettext is a tool that automatically generates the '.po' files which can then be sent to translators (or online services). As far as I understand, your project does not contain such a tool yet. Would you think it might be a good idea to add a small Dart utility for that purpose to your project?
It might be sufficient to run a regular expression against project files (at least for most cases). But maybe I am overlooking something there. If you feel this could benefit your project I might work on a pull request.
Is there a way to detect missing translations without running the code?
e.g. in my app I am not testing every Snackbar, Dialog or smaller UI Widget, therefore those string do not show up when using expect(Translations.missingKeys, isEmpty); expect(Translations.missingTranslations, isEmpty);
in a test.
I am thinking about something like a additional rule for the dart analyzer, which seems not possible at the moment as mentioned here dart-lang/linter#697. An alternative for static analysis is mentioned here: dart-lang/linter#697 (comment)
Or is there a different way one could achieve this functionality?
Hello,
I see in the documentary that there is an export and an import for po. Unfortunately I don't understand how I can use it.
Are the commands for the shell?
Thanks
Right now every documentation is tells to write static fields. But this doesn't work with hot reload. I suggest to change this to getter
extension Localization on String {
get _t =>
Translations("en") +
{
"en": "Forgot Password?",
"ru": "Забыли Пароль?",
};
String get i18n => localize(this, _t);
}
can you provide more details about how to use this? or upload an example to your example proyect.
Translations.missingKeyCallback = (key, locale)
=> throw TranslationsException("Translation key in '$locale' is missing: '$key'.");
Translations.missingTranslationCallback = (key, locale)
=> throw TranslationsException("There are no translations in '$locale' for '$key'.");
Whenever I try to use this package with injectable
I get this error
NoSuchMethodError: The getter 'major' was called on null.
Receiver: null
Tried calling: major
[SEVERE] injectable_generator:injectable_builder on test/widget_test.dart:
Hi,
I'm trying the Translation by locale:
extension Localization on String {
static var _t = Translations.byLocale("en") +
{
"en": {
"Hi": "Hi",
"Goodbye.": "Goodbye.",
},
} +
{
"nl": {
"Hi": "Hallo",
"Goodbye.": "Vaarwel",
}
};
String get i18n => localize(this, _t);
}
and implement
return I18n(
initialLocale: Locale("nl"),
...
Text(
'Hi'.i18n,
),
...
but i get the following error
The following NoSuchMethodError was thrown building Consumer<RegisterViewModel>(dirty, dependencies: [_InheritedProviderScope<RegisterViewModel>]):
The method '[]' was called on null.
Receiver: null
Tried calling: []("Hi")
It does work when I use to normal way
import 'package:i18n_extension/i18n_extension.dart';
extension Localization on String {
static var _t = Translations("en") +
{
"en": "Hi",
"nl": "Hallo",
};
String get i18n => localize(this, _t);
}
What am I doing wrong?
I would want to use the byLocale because I think it's easier to maintain.
Thanks for any help
regards
Steven
Is there a way to implement localizations strings from an api or local json file. I could not find an example. Since the api call and getting local json file is async, I could not be able to find a way to implement this.
looks like plural is not working
Text('0 Selected'.i18n.plural(_itemsSelected.length)),
{
"en": "0 Selected"
.zero("0 Selected")
.one("1 Selected")
.two("2 Selected")
.many("%d Selected"),
"es": "0 Seleccionado"
.zero("0 Seleccionados")
.one("1 Seleccionado")
.two("2 Seleccionados")
.many("%d Seleccionados"),
}
The following TranslationsException object was thrown building ViewBookNotesScreen(dirty, dependencies: [MediaQuery], state: _ViewBookNotesScreenState#c9334):
Translation key in 'en' is missing: '�0 Selected�0�0 Selected�1�1 Selected�2�2 Selected�M�%d Selected'.
I just started to use your package which looks quite promising. Anyway I'm absolutely fine with having a 2 letter language code but trying
static final _t = Translations('en') +
{
'en': '<Please select a country>',
'de': '<Bitte ein Land auswählen>',
} +
{
'en': 'Country',
'de': 'Land',
};
with standard Locale( 'en', 'US' )
leads to messages
➜ There are no translations in 'en_us' for "Country".
➜ There are no translations in 'en_us' for "".
➜ There are no translations in 'de_de' for "Country".
➜ There are no translations in 'de_de' for "".
Could you add some switch to Translations
to only check the 2-letter language code?
That would even reduce a little bit more boilerplate code :-)
Considering:
static var t = Translations("pt") +
{
"pt": "ENTRAR COM GOOGLE",
"en": "ENTER WITH GOOGLE",
"es": "INICIA COM GOOGLE",
};
Results in:
➜ There are no translations in 'pt_br' for "ENTRAR COM GOOGLE".
I was expecting something like pt_pt, pt_ao, pt_br too fallback to pt (I'm lazy and don't want to translate every variant of portuguese, english and spanish)
BTW, my phone is en_US (don't know why it is trying to find pt_br)
When I run flutter pub run i18n_extension:getstrings all strings get exported, apart from interpolated strings that I generate with .i18n.fill
Is that a bug in the getstrings generator?
It seems that the generator ignores strings that have a linebreak before .i18n or .fill.
so if I have
'mysamplestring %s'
.i18n
.fill(test)
it doesnt detect the string during generation
but
'mysamplestring %s'.i18n.fill(test)
works
I assume this is a bug in how getStrings detects strings in code files
Hi, I try to fetch system locale to show content in the language of the device system but the locale that is set by default is always null which results in displaying the first language.
I have the exact same result in your example app. In your example app you support two languages: English US and Portuguese Brazil. But when I open the app, it always show content in English, even if I set device language to the second one.
EDIT: Ok, I took wrong locale to check, systemLocale is showing default locale (en_US). Yet still, the content is shown in default language instead of device locale.
Flutter localizations are still required to translated Flutter widgets. It would be great to have this integration realized within i18n.
Please have a look at the example app from https://github.com/djarjo/flutter_input
I was able to combine changing both localizations with InputLanguage
.
But it required to have I18n as topmost widget and even one more instance variable of Locale
. Maybe there is a much more elegant solution by providing something like I18n.locale
to MatterialApp
even if I18n
is a child of MaterialApp
?
Hello,
I'm using your extension were I import the translation 'bylocale' from a json file.
It is working great thank you.
I didn't find the right syntax to load plurals rules by locale, so I created them as a "regular" translations map but when I try to add them together (using + or * operator) I get
'TranslationsByLocale' is not a subtype of type 'Translations'
Please provide both:
Hi,
I've background task running in isolate, some of them throw message like this "content_of_message".i18n. Obviously i18n is not loaded in isolate, i didn't have context, so message aren't translated :).
I used to achieve that I18n.define(Locale(locale)); It works, but I got some warning because it must be used only in test environnement.
What is the best way to use i18n_extension in isolate ?
Hi,
the readme says, I should put I18n
for parameter home below MaterialApp. But when I provide routes to MaterialApp then I cannot use home, because I have one route named '/'. Where should I put I18n
correctly?
════════ Exception caught by gesture ═══════════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown while handling a gesture:
The getter 'data' was called on null.
Receiver: null
Tried calling: data
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1 I18n.of (package:i18n_extension/i18n_widget.dart:74:73)
#2 ShopAddMenu.build. (package:jtw_app_flutter/ui/entertainment/entertainmentHome/shopPublish/shopAddMenu/shop_add_menu.dart:55:16)
#3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
#4 _InkResponseState.build. (package:flutter/src/material/ink_well.dart:789:36)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#8c92c
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(398.0, 52.8)
finalLocalPosition: Offset(33.6, 28.8)
button: 1
sent tap down
════════════════════════════════════════════════════════════════════════════════════════════════════
Reading from JSON file will be Future value and cannot be applied to used as in example.
static var _t = Translations("en_us") + JsonReader.loadFromAsset();
Hi, I'm trying to translate a simple flutter application, but for some reason it doesn't work.
pubspec.yaml
i18n_extension: ^1.2.0
main.dart
import 'package:i18n_extension/i18n_widget.dart';
import 'main.i18n.dart';
...
home: I18n(child: MyHomePage(),)
...
appBar: AppBar(title: Text("i18n Demo" .i18n))
main.i18n.dart
import 'package:i18n_extension/i18n_extension.dart';
extension Localization on String {
static var t = Translations("en_us") +
{
"en_us": "i18n Demo1",
"de": "KLAPPT?",
};
String get i18n => localize(this, t);
String fill(List<Object> params) => localizeFill(this, params);
String plural(int value) => localizePlural(value, this, t);
String version(Object modifier) => localizeVersion(modifier, this, t);
Map<String, String> allVersions() => localizeAllVersions(this, t);
}
Result: Nothing. There is no error message. However, the appbar title doesn't translate - neither in english nor in german.
When using Translations.byLocale
, we should not need to provide the translations of the default locale like:
var t = Translations.byLocale("en_US") +
{
"en_us": {
"Hi.": "Hi.",
"Goodbye.": "Goodbye.",
},
};
This is boilerplate.
But if we don't provide it, an error is shown: ➜ There are no translations in 'en_US' for "Hi".
This behavior should be fixed.
I have created #25 to fix this issue, please take a look of it. Thanks.
It seems to be the default language (fallback) is not working. If some unknown language is set, for example, de_DE, the dutch(nl) translation is shown. Any English locale will display the English translation.
Main:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Timesheet',
home: I18n(child: LoginScreen()),
debugShowCheckedModeBanner: false,
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('nl', 'NL'), // nl
Locale('en', 'US'), // English
Locale('en', 'UK'), // English
]
);
}
}
Translation:
extension Localization on String {
String get i18n => localize(this, t);
String plural(int value) => localizePlural(value, this, t);
static var t = Translations('en') +
{
'en': 'Sign in success',
'nl': 'Inloggen gelukt',
} +
{
'en': 'Sign in fail',
'nl': 'Inloggen mislukt',
} +
...
}
adding the following seems to fix the issue.
localeResolutionCallback: (locale, locales) {
print("FALLBACK TO ${locale.toLanguageTag()}");
return locale;
},
Did you think that is a good idea to load translations from file through a singleton like following ?
(Why i do that ? Because a json file can be easily be shared / generated with my team)
It works, but i didn't know if it's a very bad practice...
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:i18n_extension/i18n_extension.dart';
class TranslationData {
List translations;
static final TranslationData _singleton = TranslationData._internal();
factory TranslationData() => _singleton;
TranslationData._internal();
Future initTranslations() async {
String json = await rootBundle.loadString("assets/translations.json");
TranslationData()..translations = jsonDecode(json);
}
}
extension Localization on String {
static _load() {
Translations data = Translations("id");
List translations = TranslationData().translations;
for (dynamic item in translations) {
Map<String, String> lol = Map<String, String>.from(item);
data += lol;
}
return data;
}
static var _t = _load();
String get i18n => localize(this, _t);
}
main
void main() async {
WidgetsFlutterBinding.ensureInitialized();
TranslationData translations = TranslationData();
await translations.initTranslations(),
runApp(App());
}
The json file
[
{
"id": "sign_in",
"en": "SIGN IN",
"fr": "SE CONNECTER",
"es": "CONECTARSE"
},
{
"id": "sign_up",
"en": "SIGN UP",
"fr": "S'ENREGISTER",
"es": "REGISTRARSE"
},
{
"id": "email_label",
"en": "Email",
"fr": "Email",
"es": "Email"
},
...
]
Hello. Thanks for the great plugin!
I'm having issues reloading the i18n locale programatically. If I change the language and hot reload the app everything works fine, but I basically want all the translations to change to the chosen language on the tap of a button.
I used I18n.of(context).locale = Locale($MY_NEW_LOCALE); like the docs suggested but I get the following error, and my strings don't change language... any idea how I can proceed?
I'm changing from english to arabic, so when I tap my change language button the entire app is becoming RTL (base locale is changing) but the translations don't change until I reload the app.
Thanks for the help
I/flutter (17829): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════ I/flutter (17829): The following NoSuchMethodError was thrown while handling a gesture: I/flutter (17829): The getter 'data' was called on null. I/flutter (17829): Receiver: null I/flutter (17829): Tried calling: data I/flutter (17829): I/flutter (17829): When the exception was thrown, this was the stack: I/flutter (17829): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5) I/flutter (17829): #1 I18n.of (package:i18n_extension/i18n_widget.dart:74:73) I/flutter (17829): #2 _SettingsPageState.languageButton.<anonymous closure> (package:anghamicreators/widgets/settings_page.dart:92:18) I/flutter (17829): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14) I/flutter (17829): #4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36) I/flutter (17829): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) I/flutter (17829): #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11) I/flutter (17829): #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5) I/flutter (17829): #8 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:236:7) I/flutter (17829): #9 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27) I/flutter (17829): #10 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:222:20) I/flutter (17829): #11 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) I/flutter (17829): #12 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) I/flutter (17829): #13 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) I/flutter (17829): #14 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7) I/flutter (17829): #18 _invoke1 (dart:ui/hooks.dart:273:10) I/flutter (17829): #19 _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5) I/flutter (17829): (elided 3 frames from package dart:async) I/flutter (17829): I/flutter (17829): Handler: "onTap" I/flutter (17829): Recognizer: I/flutter (17829): TapGestureRecognizer#bef9f I/flutter (17829): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (14367): [2019-11-23 04:10:51.568618 | ConsoleHandler | INFO] NoSuchMethodError: The method 'replaceAll' was called on null.
I/flutter (14367): Receiver: null
I/flutter (14367): Tried calling: replaceAll(RegExp: pattern=^[_ ]+|[_ ]+$ flags=, "")
I/flutter (14367): [2019-11-23 04:10:51.574261 | ConsoleHandler | INFO]
I/flutter (14367): [2019-11-23 04:10:51.576518 | ConsoleHandler | INFO] ------- STACK TRACE -------
I/flutter (14367): [2019-11-23 04:10:51.598902 | ConsoleHandler | INFO] #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
I/flutter (14367): [2019-11-23 04:10:51.602977 | ConsoleHandler | INFO] #1 I18n._trimLocale
package:i18n_extension/i18n_widget.dart:53
I/flutter (14367): [2019-11-23 04:10:51.603718 | ConsoleHandler | INFO] #2 I18n.localeStr
package:i18n_extension/i18n_widget.dart:48
I/flutter (14367): [2019-11-23 04:10:51.604203 | ConsoleHandler | INFO] #3 _effectiveLocale
package:i18n_extension/i18n_extension.dart:213
I/flutter (14367): [2019-11-23 04:10:51.604531 | ConsoleHandler | INFO] #4 localize
package:i18n_extension/i18n_extension.dart:48
I/flutter (14367): [2019-11-23 04:10:51.604829 | ConsoleHandler | INFO] #5 Localization.i18n
The method isn't found when I try to do this:
Text("hello %s".i18n.fill(["Test"]));
I goes the method to overwrite it in the extension is missing?
Something like
String get i18n => localize(this, _t); String plural(int value) => localizePlural(value, this, _t);
Hello, I've really loved the plugin
but when I tried to use it in a personal project it always returns Translation key in '' is missing: "Something".
it's not recognizing the Locale?
My project is this: https://github.com/luizwalber/TaskManager
It's a mess, I'm learning and building it
the translations are in the main.i18n.dart file and I use the .i18n in the files inside ui->screens
Thanks a lot for the plugin, the way to implement internationalization in flutter is horrible.
I changed the locale on my iPhone, iOS 13.3.1 to Spanish and the region to Mexico. However, The mechanisms this extension seems to use seem to be stuck at en_US.
Enhancement Request:
New parameter for I18n
to set the locale to use. Supersedes parameter initialLocale
(if both were set). Allows clean integration with MaterialApp
.
Reason: there is NO solution to properly integrate with MaterialApp (see #10 ). I have added additional reasons under that issue.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.