2

I have a modal-dialog component template, which contains the following

  <div class="header">
    {{t title}}
  </div>

So, I am using the ember-i18n [1] library to add localisation to ember. Now I am calling that component template from the actual modal dialog template:

{{#modal-dialog title="dialog.title"}}
  <h3 class="flush--top">I am a modal dialog</h5>
  <button {{action "close"}}>Done</button>
{{/modal-dialog}}

What I am trying to do here is, defining a key that is used for localisation in the dialog template, which is passed to the component template and translated there. However, this leads to the following error: Missing translation: title. So the variable title just seems to actually be treated as a string and not as a variable.

Alternatively I could translate the title in the dialog template and pass it to the component template:

dialog:

{{#modal-dialog title={{t "dialog.title"}} action="close"}}

That leads to a compiler error:

Error: Parse error on line 1:
...#modal-dialog title={{t "dialog.title"}}
-----------------------^
Expecting 'STRING', 'INTEGER', 'BOOLEAN', 'OPEN_SEXPR', 'ID', 'DATA', got 'OPEN'

Is there any way to make this happen?

[1] https://github.com/jamesarosen/ember-i18n

st-h
  • 2,444
  • 6
  • 37
  • 60

5 Answers5

2

mitchlloyd presented a great solution here: http://discuss.emberjs.com/t/need-to-pass-a-value-from-component-template-to-component/5792/6

Use the Translation suffix in the template (I was just passing a title property):

{{#modal-dialog action="close" titleTranslation="modal.title"}}
  <h3 class="flush--top">Name Change Modal</h5>
{{/modal-dialog}}

The component uses the Mixin from ember-i18n:

export default Ember.Component.extend(Em.I18n.TranslateableProperties, {
}); 

And finally in the template, just reference the translated title property:

<div class="title"> {{title}}</div>
st-h
  • 2,444
  • 6
  • 37
  • 60
2

The explanations above are not working with the latest version of ember-i18n where TranslateableProperties has been removed:

Here is how I made it work with ember-i18n 4.x and ember-cli 1.13.1:

1 - Make sure that the service i18n is injected in your component:

//initializers/i18n.js
export default {
  name: 'i18n',

  after: 'ember-i18n',

  initialize: function(_, app) {
      app.inject('controller', 'i18n', 'service:i18n');
      app.inject('component', 'i18n', 'service:i18n');
  }
};

2 - The component's template references a {{title}} property:

//templates/components/pick-card.hbs
!-- Selection of the card -->
<div class="row" style="margin-top: 40px;">
    <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-8 col-md-offset-2">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h1 class="panel-title">{{title}}</h1>
            </div>
...

3 - The template where I call my component:

//templates/security/forgot-username.hbs
{{#pick-card title-i18n="page.forgot_username"}}
{{/pick-card}}

4 - The component's controller where the magic is:

    import Ember from 'ember';
    import {translationMacro as t} from "ember-i18n";

    export default Ember.Component.extend({
      title: Ember.computed('i18n.locale', function() {
          return this.get('i18n').t(this.get('title-i18n'));
      })
    });

As described in ember-i18n doc the use of i18n.locale is crucial to make sure that the property {{title}} is translated automatically as soon as the user changes the locale.

Have fun :)

Hervé
  • 21
  • 3
1

Better way is to use the Handlebars Subexpressions:

You would use some this like this:

{{#modal-dialog title=(tv "dialog.title") action="close"}}

Here tv is the helper i have used:

And You need to register a helper for this:

Ember.Handlebars.registerHelper('tv', function (key) {
  return Em.I18n.t(key);
});

Hope this helps

0

You can compute that title property within the controller or model. So:

{{#modal-dialog title={{t "dialog.title"}} action="close"}}

Would be:

{{#modal-dialog title="dialog.translateTitle" action="close"}}

And then you could have a computed property like so:

translateTitle: function () {
  return this.translateLibraryMethodYouUse(this.get('title'));
}.property('title') 

That is obviously psuedo code, but it should work if you can get your localization into the translateTitle property. you can put that in your dialog model, or you can put it into your item controller or whatever you are using for that context.

UPDATE::

Okay, so took a look at that library. You can also try updating your controller or model with the Em.I18n.TranslateableProperties mixin to allow you to bind a translated property:

App.DialogController = Ember.ObjectController.extend(Em.I18n.TranslateableProperties, {
  titleTranslation: 'dialog.title'
});

Good luck, and hope that helps!

Matthew Blancarte
  • 8,251
  • 2
  • 25
  • 34
  • Thanks, I tried to get that going using what you described, however everything broke when I was trying to either access the value I have in the component-template from the component, or when I was trying to access the value that is set in a controller from the component-template. I have written more about these issues here: http://discuss.emberjs.com/t/need-to-pass-a-value-from-component-template-to-component/5792 – st-h Jun 29 '14 at 15:12
0

Just to update the responses here to be a little more up to date! As mentioned by @mohamedjahabersadiq, you can use Subexpressions. These also work fine in HTMLBars (>= Ember 1.10.0). However, you don't have to register a new helper, you can use the existing t helper from ember-i18n.

{{#modal-dialog title=(t "dialog.title")}}
    Hello
{{/modal-dialog}}
Richard Rout
  • 1,296
  • 1
  • 15
  • 28