Skip to content
This repository was archived by the owner on Apr 18, 2023. It is now read-only.
Closed
26 changes: 19 additions & 7 deletions addon/helper.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import Ember from "ember";

export default Ember.Helper.extend({
i18n: Ember.inject.service(),
const { get, inject, Helper, Object: EmberObject, observer } = Ember;

compute: function(params, interpolations) {
const key = params[0];
const i18n = this.get('i18n');
return i18n.t(key, interpolations);
function mergedContext(objectContext, hashContext) {
return EmberObject.extend({
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're going to run into problems when a property of objectContext changes. We'll want a test for

{{t 'some.key' obj hashKey=hashValue}}

where we change obj.someProperty and hashValue and make sure both are reflected in the translated text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point. I'll add a test.

unknownProperty(key) {
const fromHash = get(hashContext, key);
return fromHash === undefined ? get(objectContext, key) : fromHash;
}
}).create();
}

export default Helper.extend({
i18n: inject.service(),

compute([key, contextObject = {}, ...rest], interpolations) {
const mergedInterpolations = mergedContext(contextObject, interpolations);

const i18n = get(this, 'i18n');
return i18n.t(key, mergedInterpolations);
},

_recomputeOnLocaleChange: Ember.observer('i18n.locale', function() {
_recomputeOnLocaleChange: observer('i18n.locale', function() {
this.recompute();
})
});
20 changes: 17 additions & 3 deletions addon/legacy/helper.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import Stream from "./stream";
import { readHash } from "./stream";
import Ember from 'ember';

export default function tHelper(params, hash, options, env) {
const assign = Ember.assign || Ember.merge;

export default function tHelper([i18nKey, contextObject = { value: () => {} }], hash, options, env) {
const i18n = env.data.view.container.lookup('service:i18n');
const i18nKey = params[0];



var out = new Stream(function() {
const value = i18nKey.isStream ? i18nKey.value() : i18nKey;
return value === undefined ? '' : i18n.t(value, readHash(hash));

const contextObjectValue = contextObject.value();
const mergedHash = {};
assign(mergedHash, contextObjectValue);
assign(mergedHash, hash);

return value === undefined ? '' : i18n.t(value, readHash(mergedHash));
});

// Once the view is destroyed destroy the steam as well
env.data.view.one('willDestroyElement', out, function() {
this.destroy();
});

if (contextObject && contextObject.isStream) {
contextObject.subscribe(out.notify, out);
}

// observe any hash arguments that are streams:
Object.keys(hash).forEach(function(key) {
const value = hash[key];
Expand Down
52 changes: 0 additions & 52 deletions tests/acceptance/t-helper-test.js

This file was deleted.

Empty file.
23 changes: 0 additions & 23 deletions tests/dummy/app/controllers/index.js

This file was deleted.

3 changes: 2 additions & 1 deletion tests/dummy/app/locales/en/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ export default {
'no.interpolations.either': 'another text without interpolations',

'with': {
interpolations: 'Clicks: {{clicks}}'
interpolations: 'Clicks: {{clicks}}',
interpolationsWithContextObject: 'Clicks: {{clicks}}, Clicks from hash: {{otherClicks}}'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer used

},

'pluralized.translation': {
Expand Down
24 changes: 2 additions & 22 deletions tests/dummy/app/templates/index.hbs
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
<section>
<span class='no-interpolations'>{{t "no.interpolations"}}</span>
</section>

<section>
<span class='static-interpolations'>{{t "with.interpolations" clicks="45"}}</span>
</section>

<section>
<button class='increment' {{action "increment"}}>Increment Click Count</button>

<span class='dynamic-interpolations'>{{t "with.interpolations" clicks=clickCount}}</span>
</section>

<section>
<button class='change-dynamic-key' {{action "changeDynamicKey" "no.interpolations.either"}}>Change dynamic key</button>

<span class='dynamic-key'>{{t dynamicKey}}</span>
</section>

<section>
<button class='switch-to-es' {{action "switchLocale" "es"}}>Switch to Spanish</button>
<section class='no-interpolations'>
{{t 'no.interpolations'}}
</section>
147 changes: 147 additions & 0 deletions tests/unit/helper-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import Ember from 'ember';
import hbs from 'htmlbars-inline-precompile';
import { moduleForComponent, test } from 'ember-qunit';
const { run } = Ember;

moduleForComponent('no-such-component', 't helper', {
integration: true,

beforeEach() {
if (Ember.Helper == null) {
const initializer = this.container.lookupFactory('initializer:ember-i18n-legacy-helper');
initializer.initialize(this.registry);
}

const i18n = this.i18n = this.container.lookup('service:i18n');
i18n.set('locale', 'en');

this.addTranslations = function(locale, translations) {
run(i18n, 'addTranslations', locale, translations);
};
},

afterEach() {
run(this.i18n, 'destroy');
}
});

test('simple text, static key', function(assert) {
this.addTranslations('en', { 'foo.bar': 'Foo Bar' });

this.render(hbs`{{t 'foo.bar'}}`);
assert.equal(this.$().text(), 'Foo Bar');
});

test('text with HTML, static key', function(assert) {
this.addTranslations('en', { name: '<em>Name</em>:' });

this.render(hbs`{{t 'name'}}`);
assert.equal(this.$().html(), '<em>Name</em>:');
});

test('dynamic key', function(assert) {
this.addTranslations('en', { foo: 'Foo', bar: 'Bar' });
this.set('someKey', 'foo');

this.render(hbs`{{t someKey}}`);
assert.equal(this.$().text(), 'Foo');

run(this, 'set', 'someKey', 'bar');
assert.equal(this.$().text(), 'Bar');
});

test('interpolations', function(assert) {
this.addTranslations('en', { 'bowl of soup': 'A bowl of {{soup}}' });
this.set('soup', 'bisque');

this.render(hbs`{{t 'bowl of soup' soup=soup}}`);
assert.equal(this.$().text(), 'A bowl of bisque');

run(this, 'set', 'soup', 'clam chowder');
assert.equal(this.$().text(), 'A bowl of clam chowder');
});

test('interpolations with passed context', function(assert) {
this.addTranslations('en', { 'bowl of soup': 'A bowl of {{soup}}' });
this.set('soup', 'bisque');

this.set('contextObject', Ember.computed('soup', function() {
return {
soup: this.get('soup')
};
}));

this.render(hbs`{{t 'bowl of soup' contextObject}}`);
assert.equal(this.$().text(), 'A bowl of bisque');

run(this, 'set', 'soup', 'clam chowder');
assert.equal(this.$().text(), 'A bowl of clam chowder');
});

test('interpolations with passed context and a hash', function(assert) {
this.addTranslations('en', { 'bowl of soup': 'A bowl of {{soup}} or {{salad}}' });
this.set('soup', 'bisque');
this.set('salad', 'mixed greens');

this.set('contextObject', Ember.computed('soup', function() {
return {
soup: this.get('soup')
};
}));

this.render(hbs`{{t 'bowl of soup' contextObject salad=salad}}`);
assert.equal(this.$().text(), 'A bowl of bisque or mixed greens');

run(this, 'set', 'soup', 'clam chowder');
run(this, 'set', 'salad', 'cobb salad');
assert.equal(this.$().text(), 'A bowl of clam chowder or cobb salad');
});

test('interpolations with passed context and a hash - hash overrides context', function(assert) {
this.addTranslations('en', { 'A delicious entree': 'A delicious {{entree}}' });
this.set('entreeFromContext', 'steak');
this.set('entreeFromHash', 'pasta');

this.set('contextObject', Ember.computed('entreeFromContext', function() {
return {
soup: this.get('entreeFromContext')
};
}));

this.render(hbs`{{t 'A delicious entree' contextObject entree=entreeFromHash}}`);
assert.equal(this.$().text(), 'A delicious pasta');

run(this, 'set', 'entreeFromContext', 'burger');
run(this, 'set', 'entreeFromHash', 'pizza');
assert.equal(this.$().text(), 'A delicious pizza');
});

test('locale change', function(assert) {
this.addTranslations('en', { soup: 'Soup' });
this.addTranslations('zh', { soup: '湯' });

this.render(hbs`{{t 'soup'}}`);
assert.equal(this.$().text(), 'Soup');

run(this.i18n, 'set', 'locale', 'zh');
assert.equal(this.$().text(), '湯');
});

test('pluralization', function(assert) {
this.addTranslations('en', {
bowls: {
one: 'one bowl',
other: '{{count}} bowls'
}
});
run(this, 'set', 'numberOfBowls', 0);

this.render(hbs`{{t 'bowls' count=numberOfBowls}}`);
assert.equal(this.$().text(), '0 bowls');

run(this, 'set', 'numberOfBowls', 1);
assert.equal(this.$().text(), 'one bowl');

run(this, 'set', 'numberOfBowls', 2);
assert.equal(this.$().text(), '2 bowls');
});