-
Notifications
You must be signed in to change notification settings - Fork 601
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
MessageFormat formatters #563
Comments
Thanks for your message and sorry for the delayed answer. Please, use variable replacement instead, e.g.: "Balance: {currency}" or "Posted at {date}" and have the variable formatted using the appropriate formatter in your code, e.g.: Globalize.formatMessage("message", {date: Globalize.formatDate(new Date())}); If you find any problem using variable replacement instead or if you have further questions feel free to post additional comments. PS:
... and I was one of the early pushers for such API to be adopted by SlexAxton/messageformat.js (the libraries Globalize uses for mesage formar under the hoods) (link). 😄 (and Alex an Eemeli did a great work updating the library). Having said that, given variable replacement could be used instead with no prejudice in that case, we opt for that. If you want to update globalize message format to support such feature, feel free to contribute the change and I'd be happy to consider it: (a) send informal messages first to discuss the new API, then send a pull request with the implementation. |
The problem with using a formatter in the variable is that it doesn't allow you to change the format in the message file. It's hard-coded. |
I made a quick proof of concept. The issues with it are:
Globalize.b955419430 = messageFormatterFn((function( ) {
return function (d) { return "Hello World " + fmt.date(d.now, ["en"], "long"); }
})() Ideally I'd like the compiler to automatically detect the call to fmt.date, and compile the dateformatter as well, but I don't know if that's possible with the current version of MessageFormat. |
As an earlier step, could you please show me a map between each Globalize formatters option and its inlined message format representation? For example, above you mentioned
Yeap the compiler could statically parse the message and do that (i.e., reuse the message formatter parser to deduce the formatters). |
The message was This is similar to what ICU does (http://icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html), except ICU only has ICU also accepts a raw format (if the parameter is not one of the short formats), so Skeleton could be implemented in a few different ways:
The basic mapping could look like this:
But one reason I'd like to be able to customize the formatters is that I wanted to integrate globalize with Yii, and I could write custom formatters that work the same way ICU in php does (http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html#message-formatting). That way I could use the same messages in php and in javascript, which is kind of a pain right now (I have to render everything in php to get pluralization and such things, and then return the html in the ajax response).
Yeah, but for globalize I think it would be better if the custom formatter function received the Globalize instance, the same one used to render the message, so you don't have to instantiate another one and compile a new formatter each time the message is rendered (if you're not using pre-compiled files). But that requires modifying messageformat or using messageformat-parser directly. The runtime binding code is already a bit hacky, it could also be cleaned up. |
I liked it so far. /cc @jzaefferer and @alunny for their inputs. |
I've hacked messageformat so that the custom formatter function can use the same globalize instance, and the dependent formatters can be passed to globalize-compiler: nkovacs@21cb3b3#diff-731a3fca6b201d79e2639fe1456b8787L156 I'll try to clean it up and get it into messageformat.js, but for now I just wanted to show how it could be done in globalize. |
This sounds great. Any news on it? |
This is needed so that the compiler can see the runtime information attached to the function. Refs globalizejs#563
Compilation now works. The only thing that needs to be changed in globalize-compiler is the compilation order. Messageformat.js has since released a major new version, so I'll have to update that too. |
Messageformat.js 1.0 has changed so much that the hacks used to integrate it into globalize no longer work. In particular, since the runtime is no longer static, I was unable to extract it and inject it into globalize's message-runtime module. So instead I copied the messageformat compiler and runtime into globalize.js, and used messageformat-parser (which has since been extracted into a separate npm package). Since I now had direct access to the compiler, I was also able to remove the regexp hacks in messageFormatterRuntimeBind (the compiler can tell the runtime binding function what features are needed, e.g. plurals, select etc.). Here's the commit: nkovacs@1586e12 What do you think? |
These presets look nice:
Any of the below look nice to me too, except for the fact that adding a time pattern in the skeleton below will result in a datetime output, which sounds inconsistent with
|
The existing "live-patch" isn't great, but I want to avoid copying dependencies and modifying them, because this is even harder to maintain over time. We need a better approach... Are there any changes we could propose in their code that would make it easier in our side? Is there any sort of JavaScript patch we could use instead of the bunch of replaces in Gruntfile? |
About plural requiring cardinal + ordinal data... I want to avoid that. I'm wondering if |
I didn't implement the skeleton and raw options yet because I'm not sure how to do that. The rest are done: 4c95d94.
With the custom compiler, yes. I'm not sure if it's doable if using messageformat.js directly, in the current version of globalize. It probably is, but it won't be pretty. That ties into your next question.
I've used messageformat-parser from npm (it's not available in bower), so I only had to copy and rewrite the compiler and the runtime, which is relatively small, and that allowed me to customize it to globalize's needs. For example, the new messageFormatterRuntimeBind is much better. |
Could you please show me a diff? |
and
|
Yeap, but looking at a diff from the original compiler and runtime to their rewritten ones would be easier to see what the changes are. Don't worry if you don't a diff handy, I can generate one... Basically, I'm in line with your suggestion of using a newer messageformat. Although, I want to better understand the changes and impact. |
It's a bit hard to see it here because of the whitespace changes required by the coding standard: compiler.js: https://gist.github.com/nkovacs/8dea134c8af7345c1c7ed921e9dc7aad/revisions runtime.js: https://gist.github.com/nkovacs/11f320e6ae60b1dccf943768367dab4d/revisions The first revision is messageformat.js's version indented with 4 spaces (original is 2 spaces), second revision is my version. |
I used your gists and created this diff that ignores white space changes: |
@nkovacs how to you suggest we maintain these files? For instance, let's suppose messageformat publish new releases with updates to those files and we want to bring those updates in. |
Another question is, what are the challenges and cost of using the new messageformat as is? From your above comments, one of them is "They'd have to make it possible to customize the compiler", what customization would be required please? |
The problems I ran into trying to use messageformat 1.0.2:
The problems with using messageformat in general (this applies to 0.3.0 as well):
The problem is that messageformat.js compiles The minimum change required in messageformat.js would be to return the compiler's runtime property and add the arguments to its formatters object. My version does it slightly differently: Here's a complete compiled example:
and the original message was:
I'm not sure why the extra parameters are passed to messageFormatterFn, but I think that's already happening with the current version of globalize.js and pluralGenerator. |
Most globalize modules can now be used directly from within messages. Also fixes selectOrdinal not using the correct plural function. The messageformat compiler and runtime are forked from messageformat.js. Fixes globalizejs#563
Most globalize modules can now be used directly from within messages. Also fixes selectOrdinal not using the correct plural function. The messageformat compiler and runtime are forked from messageformat.js. Fixes globalizejs#563
Most globalize modules can now be used directly from within messages. Also fixes selectOrdinal not using the correct plural function. The messageformat compiler and runtime are forked from messageformat.js. Fixes globalizejs#563
Most globalize modules can now be used directly from within messages. Also fixes selectOrdinal not using the correct plural function. The messageformat compiler and runtime are forked from messageformat.js. Fixes globalizejs#563
Any update on this? I am running into this as well. The messages for me are potentially user defined so formatting the value passed in isn't an option. |
The messageformat library supports custom formatter functions. You could register globalize's formatters, so they could be used in messages, e.g.
"Balance: {0, currency}"
, or"Posted at {0, datetime, long}"
.It would also be great if there was a way to pass custom formatter functions to MessageFormat.
The text was updated successfully, but these errors were encountered: