Reputation: 9662
We have an angularJS application with multiple language support.
In our main app module, we defined:
.config(function ($translateProvider, $translatePartialLoaderProvider) {
$translateProvider.useLoader("$translatePartialLoader", {
urlTemplate: "/js/app/i18n/{lang}.json"
});
$translateProvider
.registerAvailableLanguageKeys(['en', 'fr'], {
'en_US': 'en',
'en_UK': 'en',
'en_CA': 'en',
'fr_FR': 'fr',
'fr_CA': 'fr',
'fr_BE': 'fr',
'*': 'en'
})
.fallbackLanguage('en')
.determinePreferredLanguage();
In our main controller, we have a select to change the lang, calling this function:
this.changeLang = function () {
$translate.use(self.currentLang).then(function () {
// Here we want to trigger the call to another angular i8ln file
}, function () {
MessageService.show("error", $translate.instant("lang_change_error"));
});
};
But we want to use angular i8ln power to translate some data, for example datepickers.
We understood we have to load angular i8ln locale files in our index.html where the angular app is loaded. These files contain for example:
'use strict';
angular.module("ngLocale", [], ["$provide", function ($provide) {
var PLURAL_CATEGORY = { ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other" };
function getDecimals(n) {
n = n + '';
var i = n.indexOf('.');
return (i == -1) ? 0 : n.length - i - 1;
}
function getVF(n, opt_precision) {
var v = opt_precision;
if (undefined === v) {
v = Math.min(getDecimals(n), 3);
}
var base = Math.pow(10, v);
var f = ((n * base) | 0) % base;
return { v: v, f: f };
}
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": [
"AM",
"PM"
],
"DAY": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
"ERANAMES": [
"Before Christ",
"Anno Domini"
],
"ERAS": [
"BC",
"AD"
],
"FIRSTDAYOFWEEK": 6,
"MONTH": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"SHORTDAY": [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
],
"SHORTMONTH": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"STANDALONEMONTH": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"WEEKENDRANGE": [
5,
6
],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
"mediumDate": "MMM d, y",
"mediumTime": "h:mm:ss a",
"short": "y-MM-dd h:mm a",
"shortDate": "y-MM-dd",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
"PATTERNS": [
{
"gSize": 3,
"lgSize": 3,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
{
"gSize": 3,
"lgSize": 3,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "-\u00a4",
"negSuf": "",
"posPre": "\u00a4",
"posSuf": ""
}
]
},
"id": "en",
"localeID": "en",
"pluralCat": function (n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER; }
});
}]);
But how to load the i8ln file depending on what lang is currently loaded?
I tried to change the <script>
src using ng-if
trick or string interpolation but it's forbidden to prevent XSS injection.
Thanks for your help.
Upvotes: 3
Views: 4964
Reputation: 688
Following Jack A. advice, you can easily use angular-dynamic-locale module. This module allows you to "trigger" the include of a locale file using a simple function.
Here are the steps you can follow:
You just have to follow the steps on the module README.
Especially, don't forget :
Include the tmhDynamicLocaleProvider
module in your modules array: Include the tmhDynamicLocaleProvider
module in your modules array in your main App module file: angular.module("yourApp", ["tmh.dynamicLocale", ... ]);
In your main App Module to change the locale Location config
It should looks like:
.config(function ($translateProvider, $translatePartialLoaderProvider) {
$translateProvider.useLoader("$translatePartialLoader", {
urlTemplate: "/js/app/i18n/{lang}.json"
});
$translateProvider
.registerAvailableLanguageKeys(['en', 'fr'], {
'en_US': 'en',
'en_UK': 'en',
'en_CA': 'en',
'fr_FR': 'fr',
'fr_CA': 'fr',
'fr_BE': 'fr',
'*': 'en'
})
.fallbackLanguage('en')
.determinePreferredLanguage();
// Add these lines to configure path
// and set the fallback language the same you defined above
tmhDynamicLocaleProvider.localeLocationPattern('/base/node_modules/angular-i18n/angular-locale_{{locale}}.js');
tmhDynamicLocaleProvider.defaultLocale('en');
})
You have to change /base/node_modules/angular-i18n/
for the appropriate path. Also ensure the file naming convention is respected, for example by having angular-locale_en.js
file in that directory.
tmhDynamicLocale.set()
function with appropriate locale parameter.On your code, it should look like:
this.changeLang = function () {
$translate.use(self.currentLang).then(function (lang) {
// This line will trigger the file change
tmhDynamicLocale.set(lang);
}, function () {
MessageService.show("error", $translate.instant("lang_change_error"));
});
};
Upvotes: 4