I am using the ember-i18n library for translation of static strings used throughout my application. As the language files are rather big, I do not want to load at application st
You could utilize rerender() method of the view, this way you won't have to switch to a dummy url:
updateLanguage: function(lang) {
//Send xhr to get a dictionary for corresponding language
this.getDictionary(lang).then(successCb, failureCb);
//If dictionary was retrieved, set translations property and
function successCb(response) {
Ember.I18n.translations = response;
$.each(Ember.View.views, function(index, view) {
view.rerender();
});
};
function failureCb(response) {
console.error('Dictionary for this language is not available');
};
}
I tried all the ways listed here and had various issues with all of them. I found a much more elegant hack to make this work.
CAVEAT: This only works if you are serving Ember using Rails (but could probably be adapted to work with any server-side framework).
In Rails, the i18n-js gem integrates with Rails default locales. Dynamic switching in Ember is a huge pain because you must manually redraw all views or reset the app to get the language to update when I18n.locale is changed.
The best way I have found to do it is to specify locale using parameters set on Rails, before Ember even loads.
RAILS configuration:
Make your ember#index controller action look like this:
def index
if params[:locale]
I18n.locale = params[:locale]
end
end
Then in your html template, add this single line of javascript:
<html>
<head>
<%= stylesheet_link_tag :application, :media => :all %>
<%= stylesheet_link_tag "application", 'http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,100,700' %>
<%= stylesheet_link_tag "application", 'http://fonts.googleapis.com/css?family=Roboto+Condensed:400,300,300italic' %>
<%= javascript_include_tag :application %>
<title>Review Blaster 9000</title>
<!-- SET LOCALE USING RAILS PARAMETER PARSING -->
<script>I18n.locale = '<%=I18n.locale%>';</script>
<!-- END SET LOCALE -->
</head>
<body>
<!-- Start Ember.js -->
<%= yield %>
<!-- End Ember.js -->
</body>
</html>
Then in your template, specify the language switchers like this:
<a href='/?locale=en'>English</a>
<a href='/?locale=es'>Spanish</a>
...etc...
Clicking on those links will result in a complete refresh of the app. Rails will parse the parameter, set I18n and then Ember will start with the correct value already set beforehand, so everything will draw correctly.
I have not done translations in my app yet, but I plan to do so. So I'm also interested to know what is the best solution. I will describe my current idea how I would do it with my current knowledge.
1) I would define language as a top level route.
App.Router.map(function() {
this.resource('language', {path:'/language/:lang_code'}, function() {
// All other routes
});
});
Then changing the language would be a link to Language route with corresponding language code. I would also define Language model with attributes code, name, flag etc. for this. This would be also handy when showing list of language select buttons or dropdowns.
Also when loading subroute model you already know what the langugage is and you can fetch the models in current language (for example think about blog post that is different in every language). Use this.modelFor('language') to get current language in any subroute.
2) This is tricky. AFAIK there is no public API to get current URL with all the dynamic segments. There is currentPath property in application controller, but it doesn't include dynamic route variables. There are also some Ember internal variables, but I wouldn't use them as they might change. You can also investigate current router url: this.get('router.url'). Also you can bypass ember and use window.location.href to read the URL directly. But I would not spend too much time on that. Users change their language rarely (usually on first visit only) and it's not a big problem to redirect to index route on language change. I would store it in a cookie or local storage and then there is no need to change the language later. If Ember comes up with nice and easy way to do it then you can easily add this functionality later.
3) I would not put anything into application template as it is not translated. Use language template instead of application template and then everything should re-rendered as you are switching the language.
4) I think that the texts are not automatically updating because they are not currently two-way binded. But it is fine, because it is not a very good idea to have two way bindings for all texts as it can make system slow. So just put the language as top level route and everything should work fine:)