-
Notifications
You must be signed in to change notification settings - Fork 183
Allow overriding the locale for individual translations #312
Conversation
(this.get('allowLocaleOverride') !== undefined), | ||
{ id: 'ember-i18n.locale-override' } | ||
); | ||
locale = new Locale(data.locale, this.container); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part seems inefficient, but addressing it would probably require a larger change (for instance, locales could be cached on the service when they are initialized).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- we only want to warn if
data.locale
is defined - we can make it slightly more efficient by saving off the warning text as a
const
at the top of the file - we could cache
Locale
s in a closure-local map in thelocale.js
file and use the fact that returning an object from a constructor aborts the construction:
const seenLocales = {};
function Locale(name, container) {
if (seenLocales[name]) { return seenLocales[name]; }
seenLocales[name] = this;
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we only want to warn if
data.locale
is defined
This is inside the if (data.locale && ...)
so the warning should only be seen in that case.
we could cache
Locale
s in a closure-local map in thelocale.js
file
Clever! I will see if this works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is inside the if (data.locale && ...)
d'oh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I can't help thinking that from the outside, it's very counter-intuitive that new Locale
only really constructs a new locale the first time it's called with a given argument, and thereafter just returns the previously-constructed object. At that point it's really more like a lazily-populated hash. Maybe a "locales" service or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That file is private, so we can change its API. We can change the exported function to localeFor(name, container)
, which uses the map and the Locale
constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a good simple solution, I will try going in that direction.
@jamesarosen I tried changing things to use your I've addressed the outstanding feedback and rebased. The |
@jamesarosen Any further changes needed? Could this be merged and released? (I guess it should have a changelog entry, I could write that if you like) |
When testing this in my app, I discovered a need to find whether a given translation exists in another locale. So I extracted |
@@ -13,6 +15,10 @@ export default class Locale { | |||
// 3. Default `rtl` to `false` | |||
// 4. Ensure `pluralForm` is defined | |||
constructor(id, container) { | |||
if (initializedLocales[id]) { | |||
return initializedLocales[id]; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You never populate initializedLocales
with this
after the if
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Argh. You're completely right. Unfortunately, actually doing this causes adding translations at runtime to stop working. So I guess this method of caching won't work after all. I'm really not sure how to handle this correctly, the architecture is hard for me to follow... should I just take it out for now? I can personally live with the sub-optimal performance, since my use case is not very intensive (this may be a case of premature optimization).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you try removing the if
around locale.rebuild()
in addTranslations
?
I think we need to do some substantial re-architecting anyway to support #255. Probably best to think about the two problems together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tried that, but the test for adding translations at runtime still fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I'll give #255 a shot first. I may try moving some of the addTranslations
logic into Locale
so the I18nService
doesn't have to worry about state management.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright. For now I'll proceed with using this branch in my app, since it seems stable and I haven't noticed any performance hits (I have a small number of translations, and the cross-locale lookup is only performed once on page load). I will keep an eye on that task.
@jamesarosen I've resolved conflicts with current master and removed the defunct attempt at caching. How would you like to handle this? Should it still wait on #255? Can it be merged with a potential caveat about performance? (I've been using this in production for a month now and haven't seen any breaking issues with it, but also haven't examined performance too closely) |
Sorry I've let this sit so long. I want to work on #255 very soon. I'll try to eke out some time this week. Once I have a better picture of that work, I'll let you know what we should do with this. I definitely want either this code or this idea in the project. |
Rebased this on v4.2.0 to resolve conflicts. @jamesarosen how's it going? 😃 |
I'm hoping to do some of this heavier work over the break right before the new year. I'll keep you updated. |
Hi @jamesarosen, just want to confirm whether this is still slated to be merged at some point. In our limited use case we've had no problems with it, and have been using it in production since October – but we don't want to maintain a fork of ember-i18n indefinitely. Of course, I'd be happy to write a changelog entry and wiki documentation for this feature, or any other friction-reducing tasks that would help. |
There's not much movement on ember-i18n these days because I'm working on a release for another project right now. But after that release will be some I18n work, which will be a perfect time to pick this up again. Thanks for testing it out! |
This would definitely be useful. I could use this as a way to inject missing translation fallbacks, while overriding the missingMessage function to just return the english translation. |
@jamesarosen This would be a wonderful addition! ⛵ Is there anything in particular holding this PR back? (except the failing build 😄 ) |
@Grantovich Great initiative! What do you think about this: this.trigger('missing', this.get('locale'), key, data); // current
this.trigger('missing', locale.id, key, data); // my suggestion Otherwise the missing message will trigger with the wrong locale, no? source: ember-i18n/addon/services/i18n.js Line 41 in 9e84028
|
@sandstrom Thanks for the catch – I haven't been keeping this up-to-date lately since it seems there isn't much interest in merging it, and our project that uses this fork is in maintenance mode. If @jamesarosen gives the go-ahead, I would be happy to revisit it. (tagging @jasonmit since from #381 (comment) it looks like we might be duplicating some effort) |
I just had this exact same need for a project. And I extended the i18n services with the changes from this PR and it just work. Is this something still in consideration? I think this PR is worth consideration. |
friendly ping @jamesarosen 😄 |
I don't have any objections. I'd love one of the other maintainers to take a look and help shepherd this. |
jamesarosen/ember-i18n has been deprecated in favor of ember-intl. |
I had some free time, so here is my initial stab at #298. I couldn't find a way to stub the ENV value so I could test that it's correctly loaded into the service, but I manually confirmed that it works.