Git Product home page Git Product logo

ember-intl's Introduction

This project uses GitHub Actions for continuous integration. npm Ember Observer Score

ember-intl

Installation

See https://ember-intl.github.io/ember-intl/docs/quickstart.

Features

  • 🐹 Compatible with Ember apps, v1 addons (including engines), and v2 addons.
  • 📚 Built on standards: ICU message syntax and Internationalization API.
  • 🌐 Support for 150+ languages.
  • ⚙️ Locale-aware helpers and intl service, to help you display translations, numbers, dates, etc.
  • ✅ Test helpers to check locale-dependent templates.

Documentation

Compatibility

  • Ember.js v3.28 or above
  • Node.js v18 or above

ember-intl's People

Contributors

adamacus avatar briarsweetbriar avatar buschtoens avatar cibernox avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar elwayman02 avatar greatwizard avatar greenkeeper[bot] avatar ijlee2 avatar jahrock avatar jamescdavis avatar jasonmit avatar jelhan avatar jlecomte avatar jrjohnson avatar kturney avatar longlho avatar makepanic avatar mdehoog avatar nullvoxpopuli avatar rwjblue avatar sandstrom avatar snewcomer avatar stefanpenner avatar turbo87 avatar yito-nta avatar ykaragol avatar zeppelin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-intl's Issues

intl-get template helper now returns an object instead of just the message string

We were using intl-get in templates like so:

{{intl-get 'messages.key.otherKey'}}

and it would return the message string.

It appears that this no longer works and intl-get returns an object. We now have to change all our code from above to something like this:

{{format-message (intl-get 'messages.key.otherKey')}}

Was the first example above an intended use of intl-get? Or was it always supposed to be used with format-message?

Using bound properties as message key

Hi,

I have a component that generate keys, and I want to use those as bound properties in my template, but it seems it does not work. Here is my template:

<li {{action 'setRange' range.from range.to}}>{{format-message (intl-get range.label)}}</li>

the "range.label" is a valid key that exists in my locale config, but I have a Uncaught ReferenceError: Could not find Intl object: range.label error

Thanks!

Documentation on how to include ember-intl in test suite

It would be very helpful to have some documentation showing how to use ember-intl in ember-cli tests. I currently get messages like this when running my tests:

Handlebars error: Could not find component or helper named 'format-relative'
Handlebars error: Could not find component or helper named 'intl-get'

In order to get past these, I stubbed out these methods in my setup method like this:

    component = this.subject();
    // stubs for ember-intl
    component.intl = {};
    component['format-relative'] = component.intl.get = function (str) {
      return str;
    };

But I would rather know how to include the library in the test suite.

Thanks.

TR

Version ember-intl in lock step with Ember

For example, 1.10.0 is the stable we should version this to 1.10.0. When 1.11.0 is released, we make the changes to bring it up to compat. and release 1.11.0.

This eliminates confusion around Ember version requirements.

intl.get(messageKey) doesn't work in non-template code

Ember 1.10.0, ember-intl 1.1.1

Console output

$E.intl.get('messages.phone')
undefined
$E.intl.get
ember.debug.js:32014 function (keyName) {
        return get(this, keyName);
      }

The above message key "messages.phone" does exist and is output correctly via template code. Trying to use intl.get() in a component or from the browser console (the above example used the ApplicationControler as $E) always returns 'undefined'.

[Question] Testing using PhantomJS

Hi,

After integrating ember-intl on our application, I rerun our tests and found out that all the integration tests could not initialize the app when using PhantomJS.
The error was always the same: "Can't find variable: Intl".

After some search, I found out that the problem was on the initialization of the Intl service:

    setupMemoizers: on('init', function () {
        this.setProperties({
            getDateTimeFormat: createFormatCache(Intl.DateTimeFormat),
            getRelativeFormat: createFormatCache(IntlRelativeFormat),
            getNumberFormat:   createFormatCache(Intl.NumberFormat),
            getMessageFormat:  createFormatCache(IntlMessageFormat)
        });
    }),

In this init function, we use a global variable Intl.
Where does this variable is initialized? Why does it work correctly on Chrome but not on PhantomJS?
Do I miss some imports in my tests ?

Thanks for your help 😄

Format dynamic properties

I can't figure out how to translate a string passed from the model in a dynamic template that could have various titles.
model.title = 'mytasks'
messages.mytasks 'My Tasks'

I've tried:
{{ format-message (intl-get model.title) }}
and
{{ format-message model.title }}
and
{{ format-message messages[model.title] }}

I think maybe boundProperty might do something, but I can't find any documentation on how it works.

A satisfactory solution would be to translate the property in the model, but i can't figure out how to do translations in JavaScript (outside of a template)

Deprecate Ember 1.9.x

It's complicating the design to support both Handlebars/HTMLBars. Since the features for ember-intl 1 is more or less complete, now is a good time to deprecate 1.9.

Implement a "message store"

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

RFC: "ember-lazy-intl" - explore wrapping this addon for lazy loading

While lazy loading is possible today, it takes some implementing on the consumers part to get right. You can read more about the general implementation: #18 (comment)

This proposal is to bake the most likely use case, where you want to lazy load from the asset tree your locales.

This should not be part of ember-intl directly, and instead be an addon which wraps ember-intl. This is because it makes a really bold assumption as to how people store & load their messages and would only overcomplicate ember-intl if implemented directly.

/cc @bakura10

format-message boundProperty

There is an example with boundProperty is the readme for formatMessage but I've been unable to get it to work. Currently have a desire to change text within a couple buttons / headings. I could do it with {{if}} statements but just saw this and it's just as easy for me to change the message value to look up inside the controller. Just looking for clarification on it's use. Looks like it needs the actual translation object, but I can't seem to track down the way to pull translations using this.intl (injected).

{{format-message boundProperty
    name='Jason'
    numPhotos=num
    takenDate=yesterday}}

intl-relative automatically schedules rerendering

It's common to render the changes in time as they happen, but infrequent enough to where it isn't disruptive to the user. I propose an option, disabled by default, for intl-relative to periodically re-render itself to display the change in time.

{{format-relative '2/2/2015' interval=5000}} (milliseconds)

Unable to lookup the "intl:main" service in unit tests

At the moment I'm unable to write unit tests for components that use of the format-message and intl-get helpers in the component template.

Initially, this is what I've tried when just setting the test up:

needs: [
  'locale:en-GB', 'helper:format-message', 'helper:intl-get'
]

This results in an exception when calling this.render() in the actual tests:
TypeError: Cannot read property 'on' of undefined, the stacktrace points to this line. Which makes sense as 'intl:main' is missing from the needs block.

I tried adding 'intl:main' to the needs block:

needs: [
  'intl:main', 'locale:en-GB',
  'helper:format-message', 'helper:intl-get'
]

Which also resulted in an exception:
TypeError: Attempting to register an unknown factory: intl:main``.

After digging through the ember-intl source I noticed that the ember-intl initializer sets up the intl service as intl:main instead of service:intl. Trying to inject service:intl in the needs block doesn't work either.

My best guess is that initializers don't run in a (module) unit test, resulting in intl:main never being registered on the container/app. Because the intl-get helper injects intl:main rather than service:intl, adding service:intl to the test's need block won't do anything.

At the moment, I don't even care what format-message/intl-get renders, stubbing out whatever format-message and/or intl-get needs would work just fine for me as well, I just want to be able to render the component's template without exceptions. (I just don't know how to do this)

My actual question(s):

  • Am I doing something wrong?
  • Is there any documentation that I missed that explains how to do this/make it work?
  • If I'm not doing anything wrong, is there a way to work around this (eg. stubbing intl on intl-get)?

Any answers or pointers in the right direction would be greatly appreciated!

Get Translation in JS Files with Parameters

Hi,

I use Ember-CLI 0.2.1 and Ember 1.13.0-Canary.
I need the translation in a Controller.

How can I translate my strings with parameters?

I have read this:
#60

this.intl.getTranslation(key)

But:

  1. I get a Promise Object but I need the result as a String in a for-loop
  2. How can I get the translation with Parameters? Like this:
    {{format-message (intl-get "messages.photos") name=name numPhotos=numPhotos takenDate=takenDate}}

Is there anyway? Or have I still use Ember.String.loc for my translation?

Regards

A currency-aware way to set minimumFractionDigits

When displaying currencies in our app, we more or less always want to show 2 decimal points, for cents on all numbers. We can do this with formatNumber by modifying the minimumFractionDigits attribute. This works well, but there are certain currencies that we don't want decimal points on. Namely, currencies whose base unit is also its smallest unit, like the Yen (and about 13 other currencies).

I actually think this might be a bad "feature" to add to the helper, but maybe some good advice/documentation on how to achieve this would be helpful to others.

My gut says there's a way to "reopen" the helper somewhere in my app, and force defaults for minimumFractionDigits if they aren't explicitly set. Then I can do the work to know when to set and what to set those defaults to.

Make sense? Can you think of any pretty way to do this?

Here's my relevant code from my programmatic wrapper of NumberFormat, just to give perspective on what I'm doing.

// some setup

const non100UnitDenominators = {
  bif: 1, // Burundian Franc
  clp: 1, // Chilean Peso
  djf: 1, // Djiboutian Franc
  gnf: 1, // Guinean Franc
  jpy: 1, // Japanese Yen
  kmf: 1, // Comorian Franc
  krw: 1, // South Korean Won
  mga: 1, // Malagasy Ariary
  pyg: 1, // Paraguayan Guaraní
  rwf: 1, // Rwandan Franc
  vnd: 1, // Vietnamese Đồng
  vuv: 1, // Vanuatu Vatu
  xaf: 1, // Central African Cfa Franc
  xof: 1, // West African Cfa Franc
  xpf: 1, // Cfp Franc
};

function getUnitDenominator(currency) {
  currency = currency.toLowerCase();
  return non100UnitDenominators[currency] || 100;
}

And in the actual file.

  if (options.style === 'currency') {
    // If we have a 'common' currency, which comes in 'cents', force 2 decimal points
    if (getUnitDenominator(options.currency) === 100) {
      if (typeof options.minimumFractionDigits === 'undefined') {
        options.minimumFractionDigits = 2;
      }
      if (typeof options.maximumFractionDigits === 'undefined') {
        options.maximumFractionDigits = 2;
      }
    }
  }

Would love your opinions!

Update ember-intl docs to reflect how to set formats

In the docs http://formatjs.io/ember/, section "Locale and Format Data", you should be able to define the custom formats per locale using:

  • this.intl.set('formats', {number: { EUR: { style: 'currency', currency: 'EUR' }}}) during the runtime. <-- incorrect, formats is readOnly
  • or defining app/formats.js with the corresponding settings (I don't know how to produce different settings in ember when importing a module)
  • or using app/locales/fr.js to also set specific settings for some locales <-- incorrect

Linting is not linting...

Likely a bug in ember-cli, but I need to do some investigating and send a PR to fix the issue.

Opening in an issue for tracking.

Remove injecting `intl` into all objects

Once we remove support for < 1.10 we can remove the Ember initializer which handles injecting intl instance into all popular types (view, controllers, models, components, routes).

Instead, consumers can opt for Ember.inject.service to optionally inject it:

export default Ember.Component.extend({
  intl: Ember.inject.service()
});

This would obviously be a breaking change.

Rewrite translation "resolver" logic

So the end user's locale is pt-MZ. The app has strings for pt-PTand the default en. So what I think could happen at request/init time the user's locale is resolved into one which the app supports, in this case the process would be:

  1. Does the app support pt-MZ? No.
  2. What's the parent? pt-PT.
  3. Does the app support pt-PT? Yes!

So now the app executes with pt-PT as the resolved locale, and always with en as the fallback. So if someNewMessage string hasn't been translated to pt-PT yet, the default one, en is used instead.

this.intl.set('locales', ['pt-MZ', 'en']); will result in a resolvedLocales computed property (readOnly and private) to become ['pt-PT', 'en']

This will require the CLDR extracter to pull out the parent locale information for all the locales that are not targeted from the application.

Copy/pasting from a conversation I had with @ericf

The end goal, we can support this.intl.set('locales', [navigator.language, defaultLocale]) in its various fallback scenarios based on the information the CLDR data provides.

1.0.0

  • Publish formatjs.io updates
  • npm publish 1.0.0

format-time tests fail due to timezone settings

format-time: it should return a formatted string
Expected:  "1/23/2014"
Result:    "1/24/2014"

Both dateStr and timeStamp versions of the tests are affected. Replacing GMT-0500 (EST) with GMT+0100 (CET) (my local time) fixes for me - doing the reverse in an EST timezone demonstrates the issue.

Both could be fixed by adding timeZone="UTC" to the template, like:

view = this.intlBlock('{{format-time "' + dateStr + '" timeZone="UTC"}}', {locales: 'en-US'});`

Custom date format not being used in format-message

I've added a custom date formatter to simply display the short form of a week-day, but that doesn't seem to be being used in a message. It's working with format-date but not with format-message.

Here's an example repo containing an Ember app with the code below:

Eg:

export default {
  date: {
    shortWeekDay: {
      weekday: "short"
    }
  }
};

This is then used in a message:

import Locale from 'ember-intl/models/locale';

export default Locale.extend({
  locale: 'en',
  messages: {
    test: "should be a week-day initial: {day, date, shortWeekDay}"
  }
});

When displaying this in a template I'd expect the same date format to be shown:

<p>format-date: {{format-date date format="shortWeekDay"}}</p>
<p>format-message: {{format-message (intl-get "messages.test") day=date}}</p>

But instead I get the following:

screenshot 2015-02-23 20 24 41

Support for runtime-loaded CLDR

My current project is using AMD w/ Ember. Thus during dev, we have no build step. Without the ability to load the CLDR data on-demand, I am unable to implement ember-intl.

Apart from my specific issue though, it would be good to have an option to create Locales and register them as needed during runtime. Say our backend were to have language management, with the ability to add new languages or remove languages. Currently this isn't possible as the full list of languages needs to be included when building the JS.

Using formatNumber in controller causes error

ember -v
version: 0.1.15
node: 0.10.35
npm: 2.1.8

Console Output

$E.intl.formatNumber(1000)
intl.js:132 Uncaught TypeError: Cannot read property 'locales' of undefined 
intl.js:132 exports.default.ServiceKlass.extend._format
intl.js:123 exports.default.ServiceKlass.extend.formatNumber
VM6635:2 (anonymous function)
VM6491:777 InjectedScript._evaluateOn
VM6491:710 InjectedScript._evaluateAndWrap
VM6491:626 InjectedScript.evaluate

I used the Application Controller for $E above. Not sure if use of this function is supported in controllers, but it looks to me like it is.

Allow message keys to contain dots

Basically no Ember-related i18n library does allow dots in message keys, but I've found relying solely to Ember.get a bit counter-intuitive. Granted, the implementation is simpler, since it's a core Ember tool to fetch key paths and is working pretty well, but most of the i18n backeds use a key-value store like Redis. Therefore, when fetching the translations from the server, these messages must be un-flattened first to build up a hierarchical JS object structure, something Ember i18n libraries can deal with.

Instead, just serializing a KV table into

{
  "product.info": "{product} will cost {price, number, EUR} if ordered by {deadline, date, time}",
  "product.html.info": "<strong>{product}</strong> will cost <em>{price, number, EUR}</em> if ordered by {deadline, date, time}"
}

is much more straightforward on the server then the currently required

{
  "product": {
    "info": "{product} will cost {price, number, EUR} if ordered by {deadline, date, time}",
    "html": {
      "info": "<strong>{product}</strong> will cost <em>{price, number, EUR}</em> if ordered by {deadline, date, time}"
    }
  }
}

While the filesize is somewhat bigger by default, it is negligible when gzipped. Also, the former speeds up message lookups as a byproduct.

As these two semantics are not mutually exclusive (exact key lookup first, then fall back to Ember.get), I see no disadvantage in supporting both.

Road to 2.0.0

Incomplete

  • Reverse the argument behavior of format-message
    • {{format-message 'path.to.foo.bar'}}
    • {{format-message (icu '{{population, number, integer} as of {census_date, date, long}}')}}
  • Warn with message when intl-get is passed a key that is not found (#107)
  • ember-browserify the intl deps
  • Provide a migration document with thorough instructions explaining upgrade path for breaking changes.

Completed

  • Move format message into its own formatter
    • Move the format computed prop out of service (mostly complete, format-message is last one)
  • Remove defaultLocale. Instead, declared in env configuration (the same config evaluated at build time)
  • leverage instance-initializer for injecting instead of initializer
  • Tests failing due to new addition of registry in the container. Will require changes to moduleForIntl
  • YAML translation file support
    • JSON translations are already supported, I'd like to support both for 2.0
  • When a translation is merged in from the default locale's translation file, throw a console warning at build time with the key(s) missing (mostly done, needs verifying for edge cases)
  • BREAKING: Translations now hang off translations (root folder) instead of app/locales
    • Allows to easier side-loading of translations
    • Reduces confusion between the three terms: locale, cldr, message/translation
    • Part of #67
    • Commit: dd8b808
  • Automatically merge application default locale to all translations at build time
    • Configuration of default locale is defined in EmberApp within config/environment
    • Reduces confusion around fallback/default locale logic
    • Part of #67
  • BREAKING: Translation files can be in two formats, json and yaml, instead of ES6 modules
    • JSON supported
    • Allows for easier third-party service serving translation assets
    • Commit: 411ea11
  • BREAKING: Translation modules no longer contain messages object. All translations hang off the exported parent object by default

Other

  • Move formatting logic out of service and into formatters. This will thin the service, and the service will simply proxy to the formatters
  • Remove support for 1.9 (Handlebars)
  • BREAKING: Intl service is now only injected via Ember.inject.service, no longer automatic as it's seldom needed and Ember now makes it convenient to inject services
  • ES6-ify

Consider message as default key

Hi,

When formatting message, we are forced to specify the full path: {{format-message (intl-get 'messages.foo.bar')}}.

Can't this actually always assume that messages is the root, so that it allows us to simply refer to message using "foo.bar" instead of "messages.foo.bar" ? :)

Remove subscription to the application locale

I've been following @caridy's discussions on this topic in another thread where he makes the case that subscribing to locale changes to trigger a rerender of the component/helper is not a common pattern.

For example, if the users changes their locale at runtime, any helpers rendered after the change will receive the new locale change. Anything rendered previously will stay rendered on the previous locale. Handling this really complicates the helper logic and there is overhead in subscribing to those changes for each and every helper.

The workaround would be recommending users to reload the view explicitly using a rerender where they need to immediately reflect the change.

Unfortunately, we cannot begin removing this yet because the application view is not able to rerender. This is demonstrated here http://jsbin.com/ruzuho/1/edit?html,js,console,output (click rerender twice, observe the console while doing so). So, until that bug is fixed within Ember we cannot resolve this issue.

/cc @caridy

Deprecate mandatory `messages.` prefix

Due to the internals of the intl service, it is currently required to prefix key paths with messages. (ex. messages.product.info - instead of just typing product.info).

If intl-get only uses properties on the messages object, I feel this is unnecessary, because:

  • It exposes the service internals to the end user which might change in the future
  • Makes it harder to use with i18n backends, because they know nothing about this, and therefore every message key must be prefixed to match ember-intl's semantics to be usable on the client

Related to #18

Add more examples

  • format-date missing from readme
  • Changing your locale at runtime
  • Complex uses of format-message/format-html-message
  • How computed properties might be used

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.