-
Notifications
You must be signed in to change notification settings - Fork 77
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
Store messages as FluentMessage in the runtime #365
Comments
With the proposed API, using a Alternatively, bundle.addMessages(`
foo = Foo
.bar = Bar
`);
bundle.format("foo", args, errs); // 'Foo'
const message = bundle.getMessage("foo");
message(args, errs); // 'Foo'
message.bar(args, errs); // 'Bar'
for (let name of Object.keys(message)) {
message[name](args, errs); // 'Bar'
} |
Thanks for the feedback, I was going to CC you here once I submit a draft PR in a few minutes :)
This is intentional, but I'm open to revisiting the rationale. The bundle is required for formatting anyways, because it stores other messages and terms, as well as Intl objects for the current locale. I like the fact that the API makes it explicit by putting the
Yes. The default is "pull", but thanks to the
Interesting! I haven't seen this style of API often, but I like its terseness. Would it work in typed dialects of JavaScript without specifying interfaces for each message, though? Also, using a single class with well-known methods on it might benefit performance due to how JS engines optimize classes with the constant set of fields. |
I'm with Eemeli on the question of passing a message of one bundle to evaluate in another, or, if the Looking at this from the perspective of |
I also filed #364 with the intent to remove the |
Is The answer to this question depends, I think, on where exactly we set the boundary. The base |
Yes, The way I see it, you have |
I filed #366 to discuss the implementation of this proposal. |
Thanks, @eemeli and @Pike, for the quick feedback. I'd also like to ask @spookylukey and @zbraniecki for their thoughts on this. I know that the Python and Rust implementations use the dotted approach: |
At least TypeScript should be able to represent such a FluentMessage a bit like this: interface FluentMessage {
(args: Object): string
[key: string]: (args: Object) => string
}
Besides what might happen with |
Thanks for the TypeScript example! Re. The reason why I'm pushing against the That's why in this design I'm actually trying to make it harder to query attributes on their own. Attributes are best used as translations relating to the same unit of the UI. I think of them as props passed to a React component. A tuple of question, yes answer, and no answer could be a single compound message with attributes. A list of error message, city names, or status codes should—in my opinion—be represented by multiple separate messages. |
One of goals of the new design is to expose only the minimal API surface to the consumers. In the discussion on Discourse, @eemeli has pointed out that the |
We're going to the go with the |
This is a proposal for a new API for formatting messages from bundles. It's an alternative to #208. It solves the same problems that #208 does, but in a way which doesn't regress the ability to retrieve a message representation without formatting it and cache it for subsequent formatting operations. See also #358.
The current API (
fluent
0.12)This API exposes the internal representation of th e message to the consumer. The
message
might be a primitive string, an array, or an object of{value,attrs}
. In the last case,value
maybeundefined
, a string, or an array;attrs
may beundefined
or an object of attributes whose values may again be strings or arrays.This complexity comes from the days of Firefox OS where it was imperative to minimize the size of the JSON representing translations because the storage on low-end devices was limited.
The
compound
API proposed in #208In this API design, there are two entry points. The
format
method allows to specify the attribute to format after a dot. Each attribute formatted in this manner would cause the message to be re-retrieved by the bundle internally, which isn't optimal performance-wise.The
compound
entry-point returns an object of formatted values and attributes. I'm calling it "push" because all attributes would be formatted at all times (which is probably what we want anyways for the most part). However, if a need to implement performant "pull" API arises, this method could evolve to return a lazyattributes
field which would format attributes only when queried. This idea was the gist of my comment in #208 (comment).This design hides the details of how messages are stored internally by the bundle from consumers, but it doesn't allow to retrieve a message once for later re-use when formatting the same UI widget multiple times.
The
FluentMessage
API (this proposal)In this proposal, I'd like to formalize the interface of
FluentMessage
, returned bygetMessage
.FluentMessages
would provide methods for resolving their value and attributes, and a iterable over their attributes' names. Obviously, in current JS we can't really hide the fields used for storing the parsed value and attributes, but we can hint at their being private with the_
prefix, and later on switch to proper private fields when they're standardized.This API provides better encapsulation of the runtime AST inside of the
FluentMessage
class. It supports both the "pull" and the "push" API, and allows caching of the message for multiple formatting operations.The text was updated successfully, but these errors were encountered: