Double translating using the AngularJS angular-translate library

A view that uses angular-translate to plug translated values into another translated string

For those of us who're still working with applications using AngularJS 1.x (it's still in long-term support for nearly 2 years so plenty of time to plan a migration!), localising strings in the user interface using the angular-translate library seems to be the way to go, or at least it's the library I've have exposure to anyway!

One problem I've recently needed to solve is injecting the localised names of fields into validation messages that are also localised. These messages are fairly generic, e.g. You must enter at least 3 characters for the field 'Some Field', with the same messages used throughout the application with differing minimum numbers of characters and field names plugged in as appropriate. It turns out that there is a way to do this! Starting with the assumption that your application already has angular-translate plugged in and running, a simple example of the markup in question would look a little like this:

<div translate="FIELD_LBL"></div>
<ul>
    <li translate="VALIDATION_MESSAGE" translate-values="{'field': 'The field'}"></li>
</ul>

That markup uses two translations to substitute in the text for FIELD_LBL and VALIDATION_MESSAGE, which are defined as:

app.config(function ($translateProvider) {
    $translateProvider.translations('en', {
      FIELD_LBL: 'Field Label',
      VALIDATION_MESSAGE: 'The value entered into \'{{field}}\' is not valid'
    });;
    $translateProvider.preferredLanguage('en');
  });

With that done, running up the app shows:

The rendered markup with the two strings translated as required

So, both of the translations are being substituted which is just what we're after, but at the moment the string that's interpolated is static based on the value defined in the markup. It's a small step to convert this markup to:

<div>
    <div translate="FIELD_LBL"></div>
    <h1>
        {{ vm.Something }}
    </h1>
    <ul>
        <li translate="VALIDATION_MESSAGE" translate-values="{'field': '{{ vm.label | translate }}'}"></li>
    </ul>
</div>

And then add a little to the controller:

controller: [function ()
{
    var vm = this;
    vm.label = 'FIELD_LBL';
}],

Of course, in a production app vm.label wouldn't be hard-coded in the controller, it'd be passed in, but with this in place we do get the desired output which is a translated string interpolated into another translated string:

One translated string, slotted into another at run-time

About Rob

I've been interested in computing since the day my Dad purchased his first business PC (an Amstrad PC 1640 for anyone interested) which introduced me to MS-DOS batch programming and BASIC.

My skillset has matured somewhat since then, which you'll probably see from the posts here. You can read a bit more about me on the about page of the site, or check out some of the other posts on my areas of interest.

No Comments

Add a Comment