8

I need to implement an application with multi-language support using an AngularJS front-end and a Ruby on Rails server. I am looking for a reasonable approach to render translated templates in multiple languages. I have come up with an approach I would like feedback on.

In the Angular routes definitions, set the template property to an html partial that just has an ng-include with the src attribute value set by the controller. This approach is needed to dynamically modify the path to the template to be fetched from the server; it is described here: AngularJS - How to use $routeParams in generating the templateUrl?

So the Angular route config would look like:

angular.module('myApp', []).
    config(function ($routeProvider) {
        $routeProvider.when('/sites/new', {
            template: '<div ng-include src="templateUrl"></div>',
            controller: 'RouteController'
        });
    });

And the controller would look like:

// Set a prefix on the URL path, something like “es”
function RouteController($scope, $routeParams) {
    $scope.templateUrl = $routeParams.locale + "/template/sites/site";
}

Here $routeParams.locale is used to set the locale, but could be a variable set by user action. The approach for dynamically modifying the template URL path to add a locale prefix seems a bit convoluted, but I know of no other way.

On the Rails side, in routes.rb, add a route:

match '/:locale/template/*template' => 'template#get'

The route uses route globbing so the params[:template] value can be a multi-level path. The TemplateController#get action just renders the partial determined by params[:template] The Template controller code is something like:

class TemplateController < ApplicationController
    layout false
    caches_page :get

    def get
        render(template: "template/#{params[:template]}")
    end
end

The Rails I18n support for translations is used in the erb templates, translating according to the locale parameter. In production, caching would be turned on. This would avoid incurring translation overhead. The locale prefix of the URL path would result in a per language set of translated templates to be cached.

This approach pushes translations processing to the server side as much as possible.

Is there any fundamental problems with this approach?

Could it be done better?

Community
  • 1
  • 1
TsenYing
  • 280
  • 4
  • 10

2 Answers2

2

You may be interested in the angular-translate module.

ndequeker
  • 7,932
  • 7
  • 61
  • 93
Pascal Precht
  • 8,803
  • 7
  • 41
  • 53
1

We achieved client side internationalization in AngularJS with the i18next JQuery plugin http://i18next.com/ and created a filter called i18n.

When you initialize the Angular Application, you initialize the i18n plugin where you can provide a pattern to locate the file containing labels, and in the template use this as an example for binding labels and values.

{{'mynamespace:labels.firstname' | i18n}}

where "mynamespace" is used to separate your labels logically and used to locate JSON files with the labels. Within json files you can have one or more JSON objects with labels as properties. In the above example, the file called mynamespace-i18n-en-US.js if you provided a pattern __ns-i18n-__lng__.js

Is there a reason why the translation has to happen on the server?

Do you really need to translate the entire template?

Ketan
  • 5,861
  • 3
  • 32
  • 39
  • 2
    For translations that need to happen dynamically on the browser, I use a similar approach using the i18n-js gem: https://github.com/fnando/i18n-js. The advantage of translation on the server side is that the overhead of translation only needs to get done once (if the translated template is cached). – TsenYing Apr 19 '13 at 22:23