Giter Site home page Giter Site logo

Examples of fallbacks? about formatjs HOT 27 CLOSED

formatjs avatar formatjs commented on May 2, 2024
Examples of fallbacks?

from formatjs.

Comments (27)

ericf avatar ericf commented on May 2, 2024

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 Intl APIs

from formatjs.

pselden avatar pselden commented on May 2, 2024

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.

from formatjs.

StoneCypher avatar StoneCypher commented on May 2, 2024

@pselden and I just started chatting about this on IRC.

Might be nice to have fallback strategy configurable at create time. undefMesg: 'throw' would work as today, : {kind:'log', fallback: '['fr-FR'], default: 'foo'} would allow error messages to console, pull from French if possible, and return a fixed string if not (default to en-US and empty string if not provided respectively,) {kind:'ignore',...} would behave like 'log' but without the console behavior, and undefined would act like throw to keep old code from breaking.

Another nice thing about that approach is it's easy to extend if other behavior is needed.

from formatjs.

StoneCypher avatar StoneCypher commented on May 2, 2024

I would be willing to do this if it seemed sensible to people upstream

from formatjs.

ericf avatar ericf commented on May 2, 2024

@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 "" as the button label, then you'd unknowingly be making the page unusable to the French user.

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.

from formatjs.

StoneCypher avatar StoneCypher commented on May 2, 2024

@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.

from formatjs.

caridy avatar caridy commented on May 2, 2024

Guys, loading the messages in fr and in en for some users just to have a fallback mechanism is not realistic for production system. as @ericf mentioned, this is suppose to happen during the build process where you have the domain of locales that your application is suppose to support, and you have all messages in all language that you can preprocess (we call this completion process) to produce a valid list of messages that are required by your application for each supported language, this will guarantee that the "save" button (from @ericf's examples) will alway have a message that can be rendered accordingly.

We will work on providing guidance and probably a set of tools to support this use-case.

from formatjs.

caridy avatar caridy commented on May 2, 2024

... also, if you really want to implement a runtime fallback, u just need to create a shim for the formatMessage helper, to massage the message before propagating it into the real formatMessage implementation.

from formatjs.

StoneCypher avatar StoneCypher commented on May 2, 2024

k

from formatjs.

mschipperheyn avatar mschipperheyn commented on May 2, 2024

@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.

from formatjs.

Dakuan avatar Dakuan commented on May 2, 2024

@mschipperheyn Agree completely, we are going to have to run a fork for now, see #56

from formatjs.

caridy avatar caridy commented on May 2, 2024

@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?

from formatjs.

Dakuan avatar Dakuan commented on May 2, 2024

@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...

from formatjs.

Dakuan avatar Dakuan commented on May 2, 2024

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 💐

from formatjs.

pselden avatar pselden commented on May 2, 2024

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.

from formatjs.

caridy avatar caridy commented on May 2, 2024

@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 fr.json, but a missing SAVE message within in, which is a new entry in en.json, and should be propagated, specially if you have a separate tool to consume en.json to produce all the other files based on those entries.

from formatjs.

mschipperheyn avatar mschipperheyn commented on May 2, 2024

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

from formatjs.

Dakuan avatar Dakuan commented on May 2, 2024

@mschipperheyn and Rails...

from formatjs.

pselden avatar pselden commented on May 2, 2024

@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!"
}

from formatjs.

caridy avatar caridy commented on May 2, 2024

@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

from formatjs.

ericf avatar ericf commented on May 2, 2024

@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.

from formatjs.

StoneCypher avatar StoneCypher commented on May 2, 2024

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.

from formatjs.

ericf avatar ericf commented on May 2, 2024

Respectfully, something failing in production seems like a worst case to me.

@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.

from formatjs.

StoneCypher avatar StoneCypher commented on May 2, 2024

@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.

from formatjs.

StoneCypher avatar StoneCypher commented on May 2, 2024

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.

from formatjs.

ericf avatar ericf commented on May 2, 2024

@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!

from formatjs.

ericf avatar ericf commented on May 2, 2024

See: #162

from formatjs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.