Skip to content
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

Implement a "message store" #18

Closed
jasonmit opened this issue Feb 5, 2015 · 13 comments
Closed

Implement a "message store" #18

jasonmit opened this issue Feb 5, 2015 · 13 comments

Comments

@jasonmit
Copy link
Member

jasonmit commented Feb 5, 2015

The following API should be supported.

this.intl.addMessage('en', 'greeting', 'hello');
this.intl.addMessage('fr-FR', 'greeting', 'bonjour');

Push multiple messages. Note: this should do a merge and should not replace the entire locale's message object and should support nested objects.

this.intl.addMessages('en', {
  greeting: 'hello',
  bye:      'goodbye'
});

Ideally these would be used on ready, initialize, or a route hook to push messages to a locale but can happen at any point at runtime.

/cc @zeppelin @ericf

Inspired from the feedback on https://twitter.com/xeppelin/status/563319454193291264

@jasonmit
Copy link
Member Author

jasonmit commented Feb 6, 2015

Loosely related to #3

@zeppelin
Copy link
Contributor

zeppelin commented Feb 6, 2015

👍 I like the idea

@caridy
Copy link

caridy commented Feb 6, 2015

I like it, but lets keep in mind that this is suppose to be a one time operation, let's not over complicate it with a deep merge, we can do a swallow merge, and warn if we are overriding any top level entry.

@jasonmit
Copy link
Member Author

jasonmit commented Feb 7, 2015

#26 will resolve this

@jasonmit
Copy link
Member Author

jasonmit commented Feb 9, 2015

addMessage/addMessages is now on master.

@jasonmit jasonmit closed this as completed Feb 9, 2015
@bakura10
Copy link

Could this actually be made automatic when the locale change? For instance, there could be a new option called root URL (app.myapp.com/assets/locales), and whenever the locale change through an observer, the library automatically tries to retrieve the new locale by appending it (so if we switch to fr, it will load app.myapp.com/assets/locales/fr.json), and automatically push all the messages.

@jasonmit
Copy link
Member Author

@bakura10 there are so many options when it comes to how people store their messages. For example, some may store them externally and fetch via an API call, others may store them on a CDN, and lastly others may choose the static approach which is baked in to ember-intl.

The best I can do without terribly overcomplicating the design is provide a hook to allow people to push messages into the locale object. If you want to sideload your messages, ember g locale <localename> and do not populate the locale. The reason you need to create an empty locale is because at build time, I construct an object with CLDR data based on the modules within app/locales/*.

Now if you want to side load, push your json files to the asset/public tree and you can load them via XHR.

All that said, I'm opened to implementing what you described as another addon which wraps ember-intl.

@bakura10
Copy link

No problem, that makes sense. Although I think that it is quite safe to consider locales as a kind of static asset similar to JS or CSS. Therefore, serving them through a CDN makes sense ;).

It's not complicated to do anyway, as soon as you offer a hook to dynamically load locales, I'm happy with it :)

@jasonmit
Copy link
Member Author

Sorry, I was on my phone so perhaps I wasn't clear. It is possible today now that I added the addMessage/addMessages hooks. The loading of the modules and creating/moving the json files to the asset tree is left up to the implementer. But here is a likely scenario how you would want it to work:

var ApplicationController = Ember.Controller.extend({
  actions: {
    'change-locale': function(localeName) {
      // you would be responsible for pushing the json files to /assets/messages/
      request.get('/assets/messages/' + localeName + '.json').then(function (data) {
        this.intl.addMessages(localeName, data);
        this.intl.set('locales', [localeName]); // once the data is loaded change the locale
      }.bind(this));
    }
  }
});

export default ApplicationController;

But as I was saying, I could wrap ember-intl to support this lazy loading approach in a separate addon. Or, you're free to take kick start this idea and I'd be happy to assist.

And as I mentioned above in my previous post, there is some magic that happens on build time to extract the CLDR data for the locales you have modules for. So, in your case you would still want to generate the locale modules but leave them empty. Perhaps as part of lazy-ember-intl, we can move this to the Brocfile or config/environment.js configuration and opt out of the existing behavior -- allowing you to also lazy load the CLDR data.

I did not want to make the CLDR "static" when running ember g locale <locale> since it's likely to change over time (and in fact it is very soon). By keeping it out of sight, it allows me to upgrading the underlying Intl* deps w/o breaking everyone's app :)

Here is where that magic takes place: https://github.com/yahoo/ember-intl/blob/master/index.js#L95-L105

@caridy
Copy link

caridy commented Feb 15, 2015

@bakura10 you should read this one: formatjs/formatjs#39 (comment)

changing locales on the fly is tricky, it is risky, and it add a lot of complexity that I'm 99% you don't really need. how many time your users will change locales? jejeje

@gigafied
Copy link

@jasonmit I actually have a need for dynamically loading the CLDR as well, I'm trying to figure out the best way of doing this. Currently the Locale model isn't even exposed anywhere, unless I do App.__container__.lookupFactory('ember-intl@model:locale') which is not ideal at all.

@jasonmit
Copy link
Member Author

@gigafied could you open up a separate issue for this.

Currently the Locale model isn't even exposed anywhere, unless I do App.container.lookupFactory('ember-intl@model:locale') which is not ideal at all.

What are your plans to do with the factory at runtime? Create Locale Models and register them to the container? I'd like to know your use case to better understand.

@gigafied
Copy link

Sure thing. #69

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants