Code Monkey home page Code Monkey logo

Comments (11)

ericf avatar ericf commented on May 23, 2024

One of the biggest limitations of this library right now is how all of the helper functions are stuck within registerWith.

This is mainly because of {{formatHTMLMessage}} needing to access the correct Handlebars.SafeString constructor. We can look into changing this where each helper that needs access to Handlebars will either reference it as a global in the browser, or call require('handlebars') in Node. While this will make the helper functions more portable, there will be still be the problem of needing to access Ember.Handlebars (or whatever the namespace is) for Ember.


Also, @jasonmit has already begun working on an Ember CLI Add-on for FormatJS.

from handlebars-intl.

jasonmit avatar jasonmit commented on May 23, 2024

@clarle one other caveat, block helpers do not use registerBoundHelper (intl, intlGet). So registerWith needs to account for both helper types.

So far, I've opted for forking handlebars-intl since there are a few other edge cases like this. But I have an issue opened to come back to see what we can do to make handlebars-intl more reusable with Ember.Handlebars.

If you would like to collaborate on this, I'll invite you to my private repo on git.corp and we can tackle these issues together.

from handlebars-intl.

bakura10 avatar bakura10 commented on May 23, 2024

Hi,

This library is currently not easy at all to work with Ember. After a lot of tries, I've found a way to make it work. First, create an initializer:

import Ember from 'ember';
import locales from '../locales/locales';

/**
 * Configure the Intl
 */
export function initialize() {
  window.HandlebarsIntl.registerWith(window.Handlebars);

  var lookUp = ['formatDate', 'formatTime', 'formatRelative', 'formatNumber', 'formatMessage', 'formatHTMLMessage'],
      helpers = {};

  for (var key in window.Handlebars.helpers) {
    if (lookUp.contains(key)) {
      helpers[key] = window.Handlebars.helpers[key];
    }
  }

  Ember.Handlebars.registerBoundHelper('formatDate', function(value, hash) {
    if (typeof hash === 'object') {
      hash = hash.hash;
    }

    return helpers['formatDate'](value, hash, {data: {intl: locales}});
  });

  Ember.Handlebars.registerBoundHelper('formatTime', function(value, hash) {
    if (typeof hash === 'object') {
      hash = hash.hash;
    }

    return helpers['formatTime'](value, hash, {data: {intl: locales}});
  });

  Ember.Handlebars.registerBoundHelper('formatNumber', function(value, hash) {
    if (typeof hash === 'object') {
      hash = hash.hash;
    }

    return helpers['formatNumber'](value, hash, {data: {intl: locales}});
  });
}

export default {
  name: 'setup-intl',
  initialize: initialize
};

What this code does is registering the helper using the "registerWith" method, then manually registering all of them again but as bound helper (in this code I've only registered the helper I'm using, but you could add formatMessage too). This code automatically transfers a "intl" data.

So in your "app" folder, create a "locales" folder, and a "locales.js" file, and fill it. For instnace:

export default {
  locales: 'en',
  formats: {
    date: {
      medium: {
        day: 'numeric',
        month: 'short',
        year: 'numeric'
      }
    }
  }
};

You should load the right fill according to the locale.

This is really not convenient to work with, and I hope the formatJS can come with a cleaner solution and more Emberish solution qucikly :).

EDIT : in an ideal world, an Ember-CLI addon should expose a "localesPath" in the Brocfile (and would default to "locales" folder), and a "defaultLocale" option (would default to "en"). The locale folder would contain files named after the language ("en", "fr"...). When loading, the addon would first fetch the browser language. If there is such a locale in the locales folder, it would use this locale, otherwise would fallback to "defautltLocale". It should also offer a way to dynamically force a locale.

from handlebars-intl.

ericf avatar ericf commented on May 23, 2024

@bakura10 We will be making a first-class Ember integration for FormatJS so that you don't have to hack around things like this. I've started to prototype what it would look like to add an explicit layer between the Intl* APIs and the high-level integrations since the integrations essentially do very similar things.

This "helpers" layer would provide wrapper functions over top of the Intl* APIs, normalize arguments, cache the underlying Intl* instances, and possibly provide the locale data. Having this layer would mean the integrations libs themselves would become even smaller and be much easier to write since they can all depend on this core "helpers" layer.

from handlebars-intl.

jasonmit avatar jasonmit commented on May 23, 2024

in an ideal world, an Ember-CLI addon should expose a "localesPath" in the Brocfile (and would default to "locales" folder), and a "defaultLocale" option (would default to "en"). The locale folder would contain files named after the language ("en", "fr"...). When loading, the addon would first fetch the browser language. If there is such a locale in the locales folder, it would use this locale, otherwise would fallback to "defautltLocale". It should also offer a way to dynamically force a locale.

This is something I'm experimenting with, but my approach is slightly different. It will attempt to extract all the CLDR data via configuration within your Brocfile. You're able to tell the broccoli-addon, responsible for the extracting, to extract to either the assets/locale folder or into the vendor file directly (in the case where you always have a default). These modules will all be in require syntax so that it plays nice with the ember-cli resolver. You'll also be able to add locale modules, similar to what you have above with app/locales/*, and it will skip that locale during the extracting process.

When the application is initializing, I'll check the browser language and load the locale module (if available) or defer the application from loading further while I fetch the locale module and, if needed, the Intl shim.

Something I'm still thinking about is how do we change the application-wide locale at runtime? If we take the weaving the data property through the helpers then we're adding a limitation. In order for all the helpers to rerender we would explicitly need to trigger the view's rerender instead of leveraging data binding.

from handlebars-intl.

bakura10 avatar bakura10 commented on May 23, 2024

This sounds exciting. Is there some work already to play with? :)

from handlebars-intl.

froskos avatar froskos commented on May 23, 2024

Something I'm still thinking about is how do we change the application-wide locale at runtime? If we take the weaving the data property through the helpers then we're adding a limitation. In order for all the helpers to rerender we would explicitly need to trigger the view's rerender instead of leveraging data binding.

That is quite related to the main issue I found on my way to integrate Handlebars-intl with Ember. While on the side of Format JS injecting the data looks as a good strategy, Ember is thought in a different way when it comes to rendering. Basically one could never expect to get things working just by injecting whatever into the handlebars data channel, because Ember is just agnostic to its existence.

Extending the Ember.View object will work at view rendering time. The problem comes when the Format JS helper is used inside another helper which leads it not to be calculated at Ember.View rendering time. A good example is a Format JS helper wrapped in a Ember's bound if helper. Later on, when due to a change of state, the bound helper should re-render to add the new elements, the data object will not be there. Because it was not injected there. When Handlebars calls the helper... it will not know that this data should be injected. Hence FormatJS helpers declared inside the Ember helpers will fail to find it.

from handlebars-intl.

ericf avatar ericf commented on May 23, 2024

For Ember there's now Ember Intl:
http://formatjs.io/ember/

We could could move the helpers out as exports if we wanted to only support Handlebars 3.0, which removes the need the instanceof check on SafeString instances.

from handlebars-intl.

gabel avatar gabel commented on May 23, 2024

With webpack + handlebars-loader it won't work out either. The helper should be split into seperate modules.export to be included only if required.

from handlebars-intl.

ericf avatar ericf commented on May 23, 2024

The helper should be split into seperate modules.export to be included only if required.

This is only possible now with Handlebars v3 and its improved SafeString support which now only needs to implement a toHTML() method.

But that said, it's not likely to be a high priority to refactor this package in that way. I also have no idea what Webpack + Handlebars-Loader even tries to do… but seems crazy that you wouldn't be able to call HandlebarsIntl.register() during some lifecycle event of the handlebars-loader.

from handlebars-intl.

gabel avatar gabel commented on May 23, 2024

Thanks for the feedback - i'll go with i18next and SafeString.

from handlebars-intl.

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.