Open thenitai opened 10 years ago
Hey :)
in short: this is intended. Let me explain what happens:
by default i18n will return the "key" as is, as long there is no translation found for current language. The key itself is intended to be an expression like "please translate me" and will get returned until finally translated.
2nd thing is determining languages: i18n determines them by req
headers in several ways. DefaultLanguage only get's set when req
doesn't provide one of the configured languages, no matter of status of their underlying translations.
So in your case, i18n won't switch to DefaultLanguage but will try to translate that term in current language, without finding that translated term.
That behavior is borrowed from different gettext implementations where you start working with terms in a default language (mostly en), and will add i18n later by simply adding some i18n files. So i18n should return the given key as kind of "default term".
I am just thinking about a config switch to fallback to defaultLanguage on empty terms... should work, just needs some time + testing :)
Thank you for your explanations. Coming from, say Java .properties files, the default behaviour is to fall back to English translation and show the English translated text, if the key could not be found in the current locale.
This makes totally sense, especially in a production environment. There you usually don't want that customers see a message like "please translate me". Say, I'm in German and instead of "Bitte wählen Sie eine Sprache" I see a "select_locals" (if that would be my key). I don't think that goes down well.
(Just a view of someone who has deployed a couple of applications) :-)
According to your answer above, you say that if I don't set any languages in the config, this behaviour will change? If you need someone to test, please call on me.
Thank you for all your work and time. Much appreciated.
both scenarios have their pros and cons (actually I do use both depending on use case, for more than 15years now). OK no need to discuss as there is a solution: implementing a config switch, which could even be env depended. that way you can condigure to get untranslated terms on dev and foreign language terms on prod...
Yes a config setting would be awesome. Thank you for making an awesome library even better :-)
:+1: A config Setting for 'partial' fallback!
+1
+1 for having a fallback system between supported locales if keys in one locale is only partially translated.
I've seen this has been also discussed on 18n-node-2 : https://github.com/jeresig/i18n-node-2/pull/29
well fallbacks are in for a while now, see https://github.com/mashpie/i18n-node/blob/master/test/i18n.fallbacks.js and https://github.com/mashpie/i18n-node#list-of-all-configuration-options
anything still missing for you?
Sorry, I may have understood it wrong.
The way I understand the doc
What I am looking for - maybe 'fallback' wasn't a good term to use
I couldn't manage to make this work, but let me know if I got everything wrong I'll try that once again.
Let's try to sum up a little:
So you are trying to achieve a "partial" translation, right? The only intended "fallback" is the key itself.
__('Hi Dear')
will put "Hi Dear" until translated in the corresponding fr.json file:
{
"Hi Dear": "Salut mon cher"
}
all fallback logics right now happen in stage of language guessing and represent the current state for all phrases managed.
So what you want is a fallback for translating certain phrases which will lead to mixed translated output with one phrase in fr and another de and probably some untranslated in en. I won't discuss on user experience...
use cases covered right now are:
so what you want is
use a master translation for all untranslated phrases (ie: "I translated 'Greeting' with 'Hello' in en but not yet in de and expect "Hello" from defaultLocale en instead of "Greeting" for all supported and unsupported languages which by itself will also have to follow 1-3 from above)
it could work (@see https://github.com/mashpie/i18n-node/blob/master/i18n.js#L834) by declaring multiple fallbacks, but I haven't tried yet:
i18n.configure({
// setup supported locales
locales:['en', 'fr', 'de'],
// fall back to en phrases for untranslated phrases
fallbacks:{'fr': 'en', 'de': 'en'},
// default locale for any unsported requests
defaultLocale: 'fr'
});
tl;dr: the Translation Management service I use (PhraseApp) now has a configuration to to exactly this.
I still might prefer the feature to be in the i18n module.
You got it perfectly right. As for the user experience, I agree with you. Sometimes though hot features could use a quick launch instead of waiting for translations. As long as you are aware of what you do (and don't mix several languages at the same place). Anyway, let's keep the debate aside.
I did try the fallback strategy in the past (I thought this is how it worked), and tried it again now to be sure but no, fallback only seems to work if the language is not in the locales array when configuring i18n.
I thought of a dirty hack (check if a translation is equal to its key and if so force to defaultLocale translation) , but it would have been really ugly to scale it to the whole code base.
Quick note: missing translation falling back to the key is blocking for me since I use an object notation for my keys.
Luckily for me, PhraseApp does provide this feature now.
Thanks a lot for your time Marcus.
Regarding the original request, I believe that Paxa's (unmeged) "retryInDefaultLocale" PR attempted to provide a basic fix for this, using the configured default locale as a fallback: https://github.com/mashpie/i18n-node/pull/206/commits/ee0da09cfe21c2f82f57913f94eacc2e2e4b7c15
It had an infinite recursion bug though, which I've fixed here: https://github.com/eloquence/i18n-node/commit/b2e67a8ea81da6fa5c473fcfc428e5b37f818cfa
Was this ever implemented?
The discussion about a "master language" that you always fall back on is exactly what I am in need of.
I can't even get a single fallback to work right now, if the key isn't defined in one language, but is in the other, I still get the key value back when querying.
This issue is still relevant!
How could we live without fallbacks for so many years?!
In short: i18n is about "translate on phrase to mutliple languages" while l10n is responsible to deliver one translation to the user... Or in a bit longer: https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/
So for i18n (transfare one 'hello' into multiple 'Hi', 'Salut', 'Hei', 'Witam', 'Olá') we are set. For l10n we are not. Despite some features, that can be configured like:
// fallback from Dutch to German and from any localized German (de-at, de-li etc.) to German
fallbacks: { nl: 'de', 'de-*': 'de' },
// you may alter a site wide default locale
defaultLocale: 'en',
// will return translation from defaultLocale in case current locale doesn't provide it
retryInDefaultLocale: false,
Because, okay - over time i18n and l10n got used more and more as synonyms and so we finally that ended up in adding some basic l10n to i18n.
Still I think the desired feature is best outlined in vue-i18n
fallback strategy: https://kazupon.github.io/vue-i18n/guide/fallback.html with lot's of options to rethink the l10n part of the whole i18n story in addition to what we have.
But to come back to you @kaaax0815 : What part of "The issue" do you refer to, exactly?
Maybe, just in case, you could add some failing tests to https://github.com/mashpie/i18n-node/blob/master/test/i18n.retryInDefaultLocale.js that should properly resolve and describe your issue better?
@mashpie Very cool comment! I have a bit which I wanted to localize. The user could set an env bar to a local and its not avaible use the default. I found a work around for my particular approach. By checking if the env var lang is in the languages array if not use the default. A native approach would be nicer, but not necessarily needed
doesn't that config option do the trick?
// will return translation from defaultLocale in case current locale doesn't provide it
retryInDefaultLocale: false,
while talking about env var lang
... do you use i18n within a cli or http context?
If talking about cli usage only, I'd recommend y18n https://www.npmjs.com/package/y18n to be much better focused on your use case.
@mashpie I use it for my discord bot.
and retryInDefaultLocale: false
didnt work maybe because i run setLocale
and this changes the default lang asaik
of course it should be set to true
- setLocale does not change defaultLocale
. setLocale sets the locale
on the registered object, see
https://github.com/mashpie/i18n-node#some-words-on-register-option
and
https://github.com/mashpie/i18n-node/blob/master/test/i18n.setLocale.js
i meant true. my bad. it didnt work nevertheless
Briefly looking at your repository it seams, that you are using a global singleton for both: cli and web requests. And I can't find any configure()
at all, which means that i18n will act as a singleton sharing state between all and everything within your app.
This will lead to issues with concurrency as any change to the current locale will change locales in all given contexts.
In addition, without configuration there is no context nor request object and this results in a defaultLanguage of null
or undefined
- so without any defaults there is nothing to look up, right?
So, please: Use an instance. Configure that instance with i18n.configure({...})
. Bind that to a context thru register
on configure manually or use i18n.init(req, res, next)
to automatically bind to req and res objects as context.
And please if and only if you insist on directly using i18n as a global singleton, do so by configuring it with the register: global
option. Checkout examples in tests, esp. this one: https://github.com/mashpie/i18n-node/blob/master/test/i18n.api.global.js
@mashpie I do configure a instance here: https://github.com/kaaaxcreators/Discord-MusicBot/blob/824527b00dc96d514c93db81b4e681bf7101a972/src/index.ts#L52 and because i dont have any express or stuff like that i dont have any req or res
Ok, registers to global. So setLocale should work for that Single process. Same as __()
I was looking at Server.ts and commands...
Importing i18n module won’t ensure it‘s configured when used.
To get that straight: you want to use i18n for command line only. Not for req/res cycle of a webserver?
I use my webserver only to show static text nothing translatet, so no i do Not want to use i18n for req/res cycle
Hi,
ExpressJS and Jade here. Using your fine library but running into an issue when changing locale. That is, that the key is being shown instead of the default locale (english in my case).
en.json contains this:
"select_language" : "Select language"
de.json does NOT contain it at all and what we see instead of "Select language" is the "select_language".
Using 0.4.1 (the one that comes by default when doing a npm install i18n)
Thanks for the feedback.
Kind Regards, Nitai