-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Examples of fallbacks? #35
Comments
Yes, this is a good point — the story around fallbacks for the message formatting is not something that we've fully flushed out. But the fallbacks will work correctly for Number and Date/Time formatting, as those end up delegating to the built-in |
Would you accept a patch to add an option to make getIntlMessage return "" when the message is not found instead of throwing? This would just be a stopgap until a proper fallback solution could be fleshed out. |
@pselden and I just started chatting about this on IRC. Might be nice to have fallback strategy configurable at create time. Another nice thing about that approach is it's easy to extend if other behavior is needed. |
I would be willing to do this if it seemed sensible to people upstream |
@StoneCypher I don't follow what you're suggesting. @pselden I don't think having silent "errors" — the case of an empty string — is the right idea. Imagine a label for a button, in English that's "Save", but you're rending the page in French and you don't have a translation for that message. If the fallback strategy was to insert What we've recommended teams do in the past is have their build system merge the collection of translated strings with the default locale strings so that there's a value for every message ID, even if it's in a different language. In the example above, that page, rendered in French, would simply have an English "Save" label in the button. We'd like to expand on this idea to make it easier to handle fallback string messages in apps. But I'm in favor of having explicit errors rather than "succeeding" silently which would unknowingly make the page unusable. |
@ericf I'm suggesting that the library be configurable at instantiation to let the developer choose the desired behavior, and recommending a mechanism theretowards. I'm also recommending a set of defaults which models what I believe you're suggesting as primary behavior, which I agree is correct for most cases, and which will maintain current behavior if configuration isn't added. There are cases where you actually do want it to come back with a default string if no translation is provided. One example is the way Microsoft helps developers find translatable strings in apps: their system has a dummy language which returns text with strike-through characters over it, so that you can see visually what isn't handled yet. |
Guys, loading the messages in We will work on providing guidance and probably a set of tools to support this use-case. |
... also, if you really want to implement a runtime fallback, u just need to create a shim for the |
k |
@ericf I also don't think providing empty strings is the way to go. However, in the Java world the accepted and imho best solution is to have a flag that allows you to configure message processing so that in stead of an exception, the requested key is returned (e.g. 'ui.button.save'). Having an application fail completely just because of a missing text imho is ridiculous. |
@mschipperheyn Agree completely, we are going to have to run a fork for now, see #56 |
@Dakuan, @mschipperheyn, I like the example of the "Save" button from @ericf, and a console.log just does not make the cut for us. The reality is simple, if you throw, and you provide a way for people to prevent that by implementing something custom, everyone has the ability to do what they want. But if we warn instead, what about those who want to enforce very strict rules, like we do at Yahoo? |
@caridy I'd suggest that the permissive behaviour should be the default (to make the lib friendly to work with) and for the strict behaviour to be an option or override... |
It really depends if you want something aligned with how you guys work internally or something that's going to be friendly enough for us mortals to use. I think it would be a shame if you went for the 1st option. Sorry to bang on! I really am extremely grateful that all this is available at all 💐 |
Not sure if it will be useful at all to this discussion, but here is what I came up with for providing fallbacks for each locale (uses gulp). https://gist.github.com/pselden/093965d29fc95ec7026b I decided to fall back to en as a last resort to avoid crashing the app for non-translated languages. |
@pselden that's a good starting point for a fallback mechanism. At yahoo, we also do fallback at the message level, saying: you might have |
If you want to be strict, be strict. That's why we should havê a global option to handle this strictness. All it would do is return provided key in stead of throw error. This seems like a reasonable approach that satisfies everyone. Shame to have to have to fork for this. Look at Java, this is totally standard |
@mschipperheyn and Rails... |
@caridy If I understand what you're saying correctly, that's what this does (via gulp-multi-extend). Anything from the more specific level will override the less specific level, but missing entries get filled in from the less specific levels. So a missing key in fr-FR.json will be filled by fr.json. A missing key in fr.json will be filled by en.json. Example: //fr-CA.json
{
"greeting": "Ca va?"
}
// fr.json
{
"greeting": "Bonjour!",
"goodbye": "Au revoir"
}
// en.json
{
"greeting": "Hi",
"goodbye": "Bye!",
"shout": "HEY!"
}
// becomes
//fr-CA.json
{
"greeting": "Ca va?",
"goodbye": "Au revoir",
"shout": "HEY!"
}
// fr.json
{
"greeting": "Bonjour!",
"goodbye": "Au revoir",
"shout": "HEY!"
}
// en.json
{
"greeting": "Hi",
"goodbye": "Bye!",
"shout": "HEY!"
} |
@pselden awesome! @mschipperheyn alright, I will take this conversation offline with some folks, and let's see what comes from that, no promises. /cc @ericf |
@mschipperheyn thanks for the note about Java's behavior. @pselden @Dakuan we all have the same goals here, to provide a fallback mechanism for messages. As it's been mentioned, we're starting off strict because we don't want things to fail silently. The more comprehensive fallback solution we want to provide will take a look at the whole picture to come up with the best way we can to solve the fallback case. |
Respectfully, something failing in production seems like a worst case to me. The other i18n systems I've worked with have all either provided fallback stubs, provided an explicit fallback instance, allowed the developer to specify a language as the last case language, or at a minimum provided the lookup key as the translatable text. Microsoft's implementation in particular is amusing: they will zalgo your text (I'm not kidding) so that you can see the problem. |
@StoneCypher something will always fail in production. As mentioned in this thread we want to build a comprehensive solution. Before we have that solution we don't want to swallow errors because that would be lossy and leave developers in the dark about where the issue is. |
@ericf Choosing to cause exceptions when other paths are available seems like a worst case to me. I am also not aware of other i18n library vendors who have chosen faulting over trying to continue. I don't think there's actually a need to swallow errors. It's relatively straightforward to, for example, provide a function which can be relied on to ping a server back home to say "oh actually there was an error." A great number of services exist to this end. I believe that it is a false dichotomy to suggest that causing a web application to fail is the only way around losing information that there was a fault. Most web systems in production do not work this way (though Yahoo! Mail frequently dies on these grounds, which is one of the most frustrating things about being a Yahoo! Mail user.) However, most other systems, both web and otherwise, make a best effort to continue service, and generally do not terminate under non-severe conditions. My opinion is that most people would not actually find it reasonable for a web property to fail in production under user onus merely because a build system somewhere neglected to warn a developer that the label for a tab had been overlooked. My strongly held opinion is that choosing to fail the user as the primary mechanism of aggregating defect data is a problematic choice. Users should not be QA. Faults are not, I believe, a responsible method of defect location. There are no shortage of other options. Developers need not be in the dark in order to deliver a reliable end user experience. |
Since you seemed to appreciate the Java example, I'll point out that Microsoft's web setup has no trouble aggregating fault data from all Microsoft store applications simultaneously (a rather larger contingent than the web visitors to major properties, I believe.) They do not choose the "fault so that we find out there's a problem" approach. Their model is admirable. Even the smallest of developers gets telemetry with literally zero effort, and the applications continue after a fault, quite frequently user entirely unaware. As far as i18n goes, all I can say is that the baseline Windows XLIFF implementation and the older .res implementation explicitly handle this; the SDL tools explicitly handle this; Sun/GNU .po explicitly handles this; the Java .properties implementation explicitly handles this; .TM, .UNI, and .TF explicitly handle this. Indeed, the only major internationalization format that I'm aware of that does not handle this is Apple's, which also doesn't do things like inset variables, pluralization, etc. As far as I know, every major translation system chooses to make tools like these available. Maybe you want faults in production. That's cool. A mechanism which allowed those of us who do not want that to continue, however, would be greatly appreciated. Many developers feel that faults which are preventable in production are unacceptable, and should be avoided at nearly any cost. Those, in combination with that the described costs (eg losing awareness) are relatively straightforwardly mitigated, suggest that possibly a developer chosen route might be appreciated. Thanks for hearing me out. |
@StoneCypher I'm locking this thread as this discussion is getting way out scope and going in circles. I've stated numerous times that we want to revamp how to help people deal with fallback locales and strings. This thread is about a completely optional convenience method — you should simply not call it! |
See: #162 |
There is mention of support for providing fallbacks -- locales: ['fr-FR', 'en'], but I'm not at all clear on how you'd actually use it.
In the one example you show of using multiple languages for messages, you're explicitly passing in messages['en-US'] to the root component messages prop, so I don't see how you could ever have fallback logic when you're explicitly not passing in the messages of the other locales.
The text was updated successfully, but these errors were encountered: